As a GitHub bounty hunter with previously resolved reports, this February I was invited to a pre-release of the organisation SAML single sign-on (SSO) feature for GitHub.com, which has since been deployed in production. A few hours after the invitation went live and I reached out to the GitHub team to get started, my testbed organisation received the SAML feature set.
Recovery bypass codes – similar to those used for two-factor authentication – caught my eye whilst exploring functionality linked to the single sign-on implementation.
Switching between Private Browsing windows and a range of account conditions, I observed that an unauthenticated user could download SAML recovery codes from an organisation, which are used as follows:
If your IdP is unavailable you can use a recovery code to skip single sign-on and access the [...] organization.
The report to GitHub Security was submitted immediately after tests on different network conditions succeeded. As a result, my Proof of Concept involved two URLs:
And voilà, the fully functional SAML SSO recovery codes could be viewed in neatly-formatted plaintext.
As follows is the summary of this report on my GitHub Security profile.
[SSO recovery] codes are redeemed by organization administrators in the situation when the configured SAML authentication service is unavailable.
However, proper authorization checks were missing from this endpoint and the codes could be downloaded by unauthenticated users. This would allow a compromised organization administrator account to be able to access the organization without additional SAML authentication.
We fixed this issue by performing correct authorization checks on the recovery code download endpoint. Additionally, we audited other areas of our code where similar authorization checks were performed to ensure they were properly authenticated.
In addition to receiving a GitHub Security page, the Security Bug Bounty Hunter badge was added to my GitHub profile after resolution.
I would like to thank Greg Ose for the highly responsive handling of this report, and for escalating to a quick resolution in February.
The following timestamps are provided in GMT.
- 2017-02-22 20:18 – issue reported
- 2017-02-22 20:33 – triaged and escalated
- 2017-02-22 22:36 – issue confirmed fixed, internal review started
- 2017-03-02 16:58 – bounty and extras awarded, GitHub Security profile page updated
- 2017-05-25 14:48 – blogpost disclosed
Due to the nature of this engagement, the associated HackerOne report is currently unavailable for disclosure. This blogpost has been approved for disclosure, in line with the details publicly available on my GitHub Security profile.