-
-
Notifications
You must be signed in to change notification settings - Fork 963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Allow wildcard domains for redirect_to checks #1528
Changes from 1 commit
67d79ef
b5351c3
67481b6
3d25bcc
e826cc5
add81f0
8021987
0d6e69b
31f60f5
b0931b8
17e9bcc
40c3702
008f704
3b8a606
5ff7ee5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,6 +55,14 @@ func SecureRedirectOverrideDefaultReturnTo(defaultReturnTo *url.URL) SecureRedir | |
} | ||
} | ||
|
||
// SecureRedirectToIsWhitelisted validates if the redirect_to param is allowed for a given wildcard | ||
func SecureRedirectToIsWhiteListedHost(returnTo *url.URL, allowed url.URL) bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please add tests for this? |
||
if allowed.Host != "" && allowed.Host[:1] == "*" { | ||
return strings.HasSuffix(returnTo.Host, allowed.Host[1:]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the plan for case sensitivity here?
To follow the principle of least surprise, you might want to do one of
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hostnames are case insensitive, so the correct approach would be to have the wildcard matches also case insensitive :) |
||
} | ||
return strings.EqualFold(allowed.Host, returnTo.Host) | ||
} | ||
|
||
// SecureRedirectTo implements a HTTP redirector who mitigates open redirect vulnerabilities by | ||
// working with whitelisting. | ||
func SecureRedirectTo(r *http.Request, defaultReturnTo *url.URL, opts ...SecureRedirectOption) (returnTo *url.URL, err error) { | ||
|
@@ -87,7 +95,7 @@ func SecureRedirectTo(r *http.Request, defaultReturnTo *url.URL, opts ...SecureR | |
var found bool | ||
for _, allowed := range o.whitelist { | ||
if strings.EqualFold(allowed.Scheme, returnTo.Scheme) && | ||
strings.EqualFold(allowed.Host, returnTo.Host) && | ||
SecureRedirectToIsWhiteListedHost(returnTo, allowed) && | ||
strings.HasPrefix( | ||
stringsx.Coalesce(returnTo.Path, "/"), | ||
stringsx.Coalesce(allowed.Path, "/")) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This panics if
host
is an empty string. Also, what aboutfoo.*.bar
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the cases I can think of is adding some return domain eg: page1.foo.bar or page2.foo.bar where those changes are valid. If we want to make more complicated situations work I would probably go with regex, but is this case really needed?