Deployment Job Traces and Manual Variables Accessible via GraphQL by anyone
HackerOne report #2969145 by pwnie
on 2025-02-01, assigned to @cmaxim:
Report
Summary:
The GitLab GraphQL endpoint for deployment jobs lacks independent authorization. Instead, it relies on its parent type’s authorization with field-level checks. This design flaw allows any user with at least guest access to a public project to retrieve sensitive information—namely, job traces and manual CI/CD variables—even when these details should remain confidential.
Steps to Reproduce:
-
Set Up an Environment and Deployment Job:
-
Navigate to gitlab.com and create an environment for your project (choose any name).
-
Create a deployment job for this environment. For example, if the environment is named
foobar
, use the following.gitlab-ci.yml
configuration:stages: - deploy deploy-to-foobar: stage: deploy script: - echo "Hello World" > index.html - echo "Deploying to foobar environment" environment: name: foobar url: http://foobar.example.com
-
-
Trigger the Deployment:
- Let the deployment job finish.
- Update the CI/CD variables:
- Go to Build → Jobs.
- Click on the deployment job.
- Click the circular arrows (update CI/CD variables) in the upper-right.
- Enter any value in the variables form, trigger the new job, and allow it to finish.
-
Adjust Project Privacy Settings:
- In your project settings, navigate to CI/CD → General Pipelines.
- Disable the Public pipelines option and save the changes.
-
Access the Vulnerable Endpoint with a Guest Account:
- Create a second GitLab account and add it to your project with Guest permissions.
- Log in with the second account and open the GitLab GraphQL Explorer.
-
Execute the GraphQL Query:
-
Input the following query into the explorer:
query getEnvironmentJobDetails( $projectFullPath: ID! $environmentName: String! ) { project(fullPath: $projectFullPath) { environment(name: $environmentName) { lastDeployment(status: SUCCESS) { job { trace { htmlSummary } manualVariables { nodes { environmentScope } } } } } } }
-
In the variables section, enter:
{"projectFullPath": "your/full/project/path", "environmentName": "foobar"}
Replace
"your/full/project/path"
and"foobar"
with your actual project path and environment name. -
Run the query.
-
-
Observe the Issue:
- The query response will include the job trace (
htmlSummary
) and manual variables, exposing details that should be confidential.
- The query response will include the job trace (
Impact:
An attacker with guest-level access to a public project can exploit this vulnerability to read sensitive deployment job traces and manual CI/CD variables. This exposure could lead to unauthorized access to confidential information, including external secrets or data inadvertently included in job outputs.
Components Affected:
- GitLab GraphQL API for deployment jobs.
- Job trace and manual variable data exposed via the
JobType
entity.
Recommendation:
Implement independent authorization checks within the JobType
GraphQL entity rather than solely relying on parent type checks. Enforce robust, defense-in-depth security measures to ensure that sensitive deployment details remain inaccessible to unauthorized users, regardless of project privacy settings.
Impact
An attacker with guest-level access to a public project can exploit this vulnerability to read sensitive deployment job traces and manual CI/CD variables. This exposure could lead to unauthorized access to confidential information, including external secrets or data inadvertently included in job outputs.
How To Reproduce
Please add reproducibility information to this section: