@kamilhism discovered that it was possible to list the viewer’s comments on secret Gists with a scopeless OAuth token on our GraphQL API. The secret Gist corresponding to the comment would also be accessible through the gist
field on the GistComment
object. We addressed this vulnerability by restricting the field to only return comments on public Gists if it was requested with a scopeless OAuth token.
@kamilhism discovered that an organization’s OAuth Access Policy (OAP) could be bypassed on the GraphQL API in certain circumstances by fetching a public repository at the end of the query. A single GraphQL request can fetch data within multiple different repositories. As the query executes, instance variables keep track of internal state, such as the repository to which the requested resources belong. These internal variables are then used during the permission checks, which is where OAP is checked. In some cases, these variables tracking internal state weren’t being reset and would stick around during subsequent permission checks for other resources. These later checks would see that a public repository was loaded and skip the OAP checks for certain connections on the organization
object since resources in public repositories are accessible to everyone, regardless of your organization’s OAuth Access Policy. We addressed the vulnerability by ensuring the internal state gets reset before and after any permission check is performed.
@kamilhism discovered that the caching mechanism used when previewing non-code files on GitHub.com did not correctly enforce authorization for private repositories. If a non-code file in a private repository had been recently previewed by an authorized user, an attacker could bypass authorization checks by accessing the cached version directly. This required the attacker to know the full filename of the non-code file and a valid commit hash. We addressed this issue by improving the authorization checks in the caching mechanism to restrict access to files in private repositories.
@kamilhism discovered that forking a repository would not cause the repository’s wiki to be forked immediately. Instead, the wiki was forked when the fork owner attempted to create a new wiki. This could occur long after the initial repository fork occurred and could have allowed a user to access recent wiki content from the parent wiki, even if they no longer had access to the parent repository. We addressed this issue by forking wikis at the same time as the repository.
@kamilhism discovered an issue in the way that Gist and GitHub repository archive endpoints resolve, making it possible to make the “Download ZIP” button of a Gist point to the content of a Git repository with different content. We addressed the vulnerability by altering the fallback logic of the archive lookup to segment Gist and repository lookups.
@kamilhism reported the “check if a team manages a repository” API allowed any member of an organization to verify the existence of any repository within that organization. While the API validated the user was a member of the organization, it did not ensure the user had the ability to view the repository. We addressed this by updating the authorization check done for the API endpoint.
@kamilhism reported an information disclosure bug in organization event timelines that could allow an attacker to learn the names of teams within an organization. When users were added to a team an event that contained the name of the team was added to the organization’s public event timeline. We addressed this by removing the “Team add” event from an organization’s event timeline.