Skip to content
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

Open Redirection Vulnerability #268

Closed
ahpaleus opened this issue Sep 19, 2023 · 3 comments
Closed

Open Redirection Vulnerability #268

ahpaleus opened this issue Sep 19, 2023 · 3 comments
Assignees
Labels

Comments

@ahpaleus
Copy link

ahpaleus commented Sep 19, 2023

When a logged-in user clicks on a specially crafted link with a redirect_url parameter, the user can be redirected to an external website. The user must take an action, such as clicking on a portal button or using the browser’s back button, to trigger the redirection. This could lead to phishing attacks, where an attacker tricks users into visiting a malicious website by crafting a convincing URL.

  1. When logged-in, a victim clicks on the link: https://portal.caddysecurity.network/auth/whoami?redirect_url=https://nvmgpc54pak47d02e6a1l6c6wx2oqfo3d.oastify.com

  2. Then, he clicks on the Portal button. He is redirected to the redirect_url through this request:

GET /auth/portal HTTP/2
Host: portal.caddysecurity.network
Cookie: AUTHP_SESSION_ID=REDACTED; access_token=REDACTED; AUTHP_REDIRECT_URL=https://nvmgpc54pak47d02e6a1l6c6wx2oqfo3d.oastify.com
Sec-Ch-Ua: "Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://portal.caddysecurity.network/auth/whoami?redirect_url=https://nvmgpc54pak47d02e6a1l6c6wx2oqfo3d.oastify.com
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,pl;q=0.8,ru;q=0.7
HTTP/2 303 See Other
Cache-Control: no-store
Location: https://nvmgpc54pak47d02e6a1l6c6wx2oqfo3d.oastify.com
Pragma: no-cache
Server: Fly/a0b91024 (2023-06-13)
Set-Cookie: AUTHP_REDIRECT_URL=delete; Domain=caddysecurity.network; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT;
Date: Wed, 19 Jul 2023 12:49:01 GMT
Content-Length: 0

When he uses arrows in the browser to come back to the authorization process, he can be redirected to the external domain by this request too:

GET /oauth2/google/authorization-code-callback?state=fad54088-4e3f-452b-bcdc-db409c64a703&code=4%sdfdsf-sdfsdfsdf&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&hd=caddysecurity.com&prompt=none HTTP/2
Host: portal.caddysecurity.network
Cookie: AUTHP_SESSION_ID=g36v1Ycxjb1bHcBJ3FK1C2xqUb1rLpeawaN0Nglf1bLk; AUTHP_REDIRECT_URL=https://l9ve3aj238y2lbe0s4ozz4q4avgm4lsa.oastify.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Sec-Ch-Ua: "Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "macOS"
Referer: https://portal.caddysecurity.network/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,pl;q=0.8,ru;q=0.7
HTTP/2 303 See Other
Authorization: Bearer ABC.REDACTED.REDACTED
Cache-Control: no-store
Location: https://l9ve3aj238y2lbe0s4ozz4q4avgm4lsa.oastify.com
Pragma: no-cache
Server: Fly/a0b91024 (2023-06-13)
Set-Cookie: access_token=eyREDACTED; Domain=caddysecurity.network; Path=/; Secure; HttpOnly;
Set-Cookie: AUTHP_SANDBOX_ID=delete; Domain=caddysecurity.network; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT;
Set-Cookie: AUTHP_REDIRECT_URL=delete; Domain=caddysecurity.network; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT;
Date: Wed, 19 Jul 2023 12:38:53 GMT
Content-Length: 0

To mitigate this vulnerability, perform proper redirect_url parameter validation to ensure that the redirection URLs are allowed only within the same domain or from trusted sources.

In addition, we also recommend the following long-term fixes:

  • Implement robust unit tests with different bypassing scenarios of redirect_url parameter validation. Refer to the potential URL Format Bypasses. Keep in mind that different components can use different URI parsers, which can lead to parsing confusion.
  • Use Burp Suite Professional with a scanner with both these settings enabled:
    • Audit coverage – maximum: to use the most extensive set of payload variations and insertion point options
    • Audit coverage – thorough: to try more payload variations

More information about our Caddy Security public disclosure:

@greenpau
Copy link
Owner

greenpau commented Jul 9, 2024

Added trust logout redirect uri directive that validates the redirect URL. For example, trust logout redirect uri domain authcrunch.com path /foo/bar.

case "trust":
switch {
case strings.Contains(v, "logout redirect uri"):
var domainMatchType, domain, pathMatchType, path string
argp := 3
for argp < len(args) {
switch args[argp] {
case "domain", "path":
if hasMatchTypeKeywords(args[argp+1]) {
if !arrayElementExists(args, argp+2) {
return h.Errf("%s directive %q is malformed", rootDirective, v)
}
if args[argp] == "domain" {
domainMatchType = args[argp+1]
domain = args[argp+2]
} else {
pathMatchType = args[argp+1]
path = args[argp+2]
}
argp++
} else {
if args[argp] == "domain" {
domain = args[argp+1]
domainMatchType = "exact"
} else {
path = args[argp+1]
pathMatchType = "exact"
}
}
argp++
default:
return h.Errf("%s directive %q has unsupported key %s", rootDirective, v, args[argp])
}
argp++
}
redirectURIConfig, err := redirects.NewRedirectURIMatchConfig(domainMatchType, domain, pathMatchType, path)
if err != nil {
return h.Errf("%s directive %q erred: %v", rootDirective, v, err)
}
portal.TrustedLogoutRedirectURIConfigs = append(portal.TrustedLogoutRedirectURIConfigs, redirectURIConfig)

That, in turn, enables the verification of the redirect url.

./pkg/authn/handle_external_http_logout.go:     if redirects.HasRedirectURI(r.URL) && (len(p.config.TrustedLogoutRedirectURIConfigs) > 0) {
./pkg/authn/handle_external_http_logout.go:                     if redirects.Match(redirectURI, p.config.TrustedLogoutRedirectURIConfigs) {
./pkg/authn/portal.go:  if len(p.config.TrustedLogoutRedirectURIConfigs) > 0 {
./pkg/authn/portal.go:                  zap.Any("trusted_logout_redirect_uri_configs", p.config.TrustedLogoutRedirectURIConfigs),
./pkg/authn/handle_http_logout.go:              if redirects.HasRedirectURI(r.URL) && (len(p.config.TrustedLogoutRedirectURIConfigs) > 0) {
./pkg/authn/handle_http_logout.go:                              if redirects.Match(redirectURI, p.config.TrustedLogoutRedirectURIConfigs) {

@greenpau greenpau closed this as completed Jul 9, 2024
@binarious
Copy link

@greenpau I tried adding trust logout redirect uri domain myhost path / to my authentication portal, but https://myhost/auth?redirect_url=https%3A%2F%2Fmalicoushost.com%2F still redirects to the other host. Am I doing something wrong?

@greenpau
Copy link
Owner

@binarious, thank you for testing the directive. please reach out to me on Linkedin. Will troubleshoot over Google Meet. Also, please open another issue for this and reference this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants