@asanso reported that a user could use an unverified email when creating a commit with the web-editor on GitHub.com. Commits made via web edits on GitHub.com are signed using GitHub’s key. This resulted in GitHub.com signing a commit with its key for an arbitrary, unverified, email address. We addressed this issue by validating the author’s selected email had been verified before allowing them to use it to commit via GitHub.com’s web edit flow.
@asanso identified an interesting attack against the download endpoints for our 2FA and SAML recovery codes. We make these recovery codes accessible for download as plaintext and set the content-type of these responses as text/plain
. We also set the X-Content-Type-Options: nosniff
to prevent browsers from interpreting this content as valid JavaScript or other file types. However, not all browsers currently support this header.
In the case of a browser that does not support the X-Content-Type-Options: nosniff
header, the recovery code download endpoints can be sourced as JavaScript files cross-origin. The recovery code download format coincidentally forms a valid JavaScript file with lines in the format of XXXXX-XXXXX
, ten hex digits separated by a hyphen. This is interpreted in JavaScript as the subtraction of two variables! Using this format, @asanso demonstrated that each 5 hex digit half of the recovery code could be individually enumerated by defining a valueOf
function for the corresponding variable.
While this vulnerability is mitigated in most browsers by the nosniff
header and would require a significant amount of effort to brute-force, we still made changes to fix this issue. We modified the affected recovery code endpoints to only respond to POST requests instead of GET requests. With this change, the plaintext reponses can only be trigged with a valid CSRF token, preventing them from being sourced cross-origin. This issue has been fixed in GitHub Enterprise 2.9.4, 2.8.12, and 2.7.16.
@asanso reported a vulnerability where a previously authorized OAuth application could have the scopes associated with its OAuth token removed via CSRF. Before an OAuth application has been authorized, a user is required to confirm the scopes that the OAuth application is requesting. Once authorized, future OAuth flows that contain the same requested scopes are automatically validated and the user is redirected to the OAuth application. If an OAuth application requests additional scopes, the user is required to authorize those as well.
@asanso observed that initiating an OAuth flow requesting fewer scopes did not require the user to authorize the removal of these scopes. As a result, an attacker could CSRF the OAuth flow for an authenticated user and silently remove scopes from the OAuth token associated with a previously authorized application. This could break functionality if the OAuth application relies on the scopes that were removed. We addressed this issue by requiring users to confirm any change in scopes for an authorized OAuth application.