Advisory ID: DOPPLER-PSA-2024-002 Publication Date: 2024-05-06 Revision Date: 2024-05-06 Status: Confirmed, Fixed Document Revision: 1.0

Overview

Doppler has found and resolved an issue where any user who belongs to a GitHub organization could link a preexisting Doppler GitHub App in that organization to a new Doppler workplace.

Description

On 2021-05-21, Doppler added functionality to allow users to reconnect or relink existing installations of the Doppler GitHub App.

Such behavior is not necessary for other OAuth integrations (e.g. Netlify, Vercel, and Heroku) because most OAuth integrations allow the Doppler OAuth App to be “connected” twice. For example, if a Doppler user wants to setup a Vercel integration, Doppler always redirects the user to Vercel’s OAuth endpoint, and after the flow is complete, a new OAuth access token is issued for use with the Doppler workplace.

GitHub’s OAuth app authentication model works differently from Doppler’s other OAuth integrations because the Doppler GitHub OAuth App can only be installed once on a GitHub organization. During the OAuth flow, GitHub provides Doppler with an “installation ID” which represents the trust relationship between GitHub, Doppler, and the user’s GitHub data.

The installation ID is not a secret value, it’s a monotonically increasing integer ID. As a result, GitHub cautions app developers that they should generate a user access token for users bearing the installation ID and check that the installation is associated with the user. [1]

Doppler was previously performing this check, as recommended, by verifying that users bearing a GitHub installation ID also have the ID present in their accessible installations via GET /user/installations but was not using GET /user/installations/{installation_id}/repositories because it is not relevant for Doppler’s integration model.

Doppler’s integration model is focused on team permissions rather than individual access within the context of an integration. For example, when a user installs the Doppler GitHub App to their Doppler workplace with access to some subset of repositories, all users in their Doppler workplace with the appropriate Doppler permissions can access the integration to create syncs. This behavior is by design and allows Doppler to be treated as the source of truth for secrets. By allowing users to access resources in Doppler, GitHub admins can restrict access to GitHub secrets — meaning that all secrets access is centralized and auditable in Doppler.

Doppler also allows linking of existing GitHub installations by presenting the user with GitHub installations available to their GitHub user via GET /user/installations. This would allow a user to delete a GitHub integration from Doppler and relink the underlying Doppler OAuth app installation without needing to reinstall via GitHub.

It was discovered, however, that checking GET /user/installations alone is not sufficient in determining if a user should be allowed to link an installation to a Doppler workplace because:

Impact

The effect of this vulnerability is that any user in a GitHub organization, regardless of their role, could link a preexisting Doppler GitHub OAuth App to any Doppler workplace to which they have access.

Similarly, a user who is a member of another user’s personal GitHub repo could link the owning user’s preexisting personal Doppler GitHub OAuth App to any Doppler workplace to which they have access.

Because Doppler’s integration model is team-focused, all Doppler users with access to a GitHub App installation have full access to create syncs to secrets on all repositories to which the app was initially granted.

Note that Doppler-GitHub config syncs do not support secrets import. This means that secrets can be written to GitHub secrets, but not read back into Doppler.

Doppler has no evidence to believe this has been exploited. A small subset of total GitHub Action syncs exist in multiple workplaces and all such users have been contacted directly.