Skip to content

Commit 5fffb29

Browse files
authored
More helpful error when allowed redirect domains are defined (#104)
Make the error message when a forbidden destination is given to `/redirect-to`, to help users better understand what allowed usage looks like. Motivated by #103. Before: ``` $ curl http://localhost:8080/redirect-to?url=https://google.com Forbidden redirect URL. Be careful with this link. ``` After: ``` $ curl http://localhost:8080/redirect-to?url=https://google.com Forbidden redirect URL. Please be careful with this link. Allowed redirect destinations: - example.com - example.org ```
1 parent 8d00add commit 5fffb29

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

httpbin/handlers.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"net/http"
1010
"net/url"
11+
"sort"
1112
"strconv"
1213
"strings"
1314
"time"
@@ -390,7 +391,17 @@ func (h *HTTPBin) RedirectTo(w http.ResponseWriter, r *http.Request) {
390391

391392
if u.IsAbs() && len(h.AllowedRedirectDomains) > 0 {
392393
if _, ok := h.AllowedRedirectDomains[u.Hostname()]; !ok {
393-
http.Error(w, "Forbidden redirect URL. Be careful with this link.", http.StatusForbidden)
394+
domainListItems := make([]string, 0, len(h.AllowedRedirectDomains))
395+
for domain := range h.AllowedRedirectDomains {
396+
domainListItems = append(domainListItems, fmt.Sprintf("- %s", domain))
397+
}
398+
sort.Strings(domainListItems)
399+
formattedDomains := strings.Join(domainListItems, "\n")
400+
msg := fmt.Sprintf(`Forbidden redirect URL. Please be careful with this link.
401+
402+
Allowed redirect destinations:
403+
%s`, formattedDomains)
404+
http.Error(w, msg, http.StatusForbidden)
394405
return
395406
}
396407
}

httpbin/handlers_test.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func assertBodyEquals(t *testing.T, w *httptest.ResponseRecorder, want string) {
7474
t.Helper()
7575
have := w.Body.String()
7676
if want != have {
77-
t.Fatalf("expected body = %v, got %v", want, have)
77+
t.Fatalf("expected body = %q, got %q", want, have)
7878
}
7979
}
8080

@@ -1239,6 +1239,13 @@ func TestRedirectTo(t *testing.T) {
12391239
WithObserver(StdLogObserver(log.New(io.Discard, "", 0))),
12401240
).Handler()
12411241

1242+
allowedDomainsError := `Forbidden redirect URL. Please be careful with this link.
1243+
1244+
Allowed redirect destinations:
1245+
- example.org
1246+
- httpbingo.org
1247+
`
1248+
12421249
allowListTests := []struct {
12431250
url string
12441251
expectedStatus int
@@ -1257,6 +1264,9 @@ func TestRedirectTo(t *testing.T) {
12571264
w := httptest.NewRecorder()
12581265
allowListHandler.ServeHTTP(w, r)
12591266
assertStatusCode(t, w, test.expectedStatus)
1267+
if test.expectedStatus >= 400 {
1268+
assertBodyEquals(t, w, allowedDomainsError)
1269+
}
12601270
})
12611271
}
12621272
}

0 commit comments

Comments
 (0)