Why One File Read Can Compromise Your Entire CI/CD Platform
🛡️ Security Intermediate 6 min read

Why One File Read Can Compromise Your Entire CI/CD Platform

A CI/CD server holds the keys to every environment it deploys to. Here is why an information-disclosure bug on GitLab is a credential-theft event, and how to limit the blast radius.

Published: September 12, 2026 • Updated: September 12, 2026
ci/cdsecrets managementsupply chainrisk

The September 2026 GitLab flaw CVE-2026-85706 was, on its face, an information disclosure bug. An unauthenticated attacker could read files from the server. No code execution, no privilege escalationPrivilege Escalation🛡️An attack technique where an adversary gains elevated access rights beyond what was initially granted., no write access. It still scored a perfect 10.0 on CVSS, and CISA gave federal agencies three days to fix it. The reason is that on a CI/CD platform, the difference between reading one file and owning the environment is small. This piece explains why, and what that means for how you should classify these systems.

The Secrets File Is a Master Key

GitLab's backup documentation is unusually direct about its most sensitive file. On Linux package installations, the secrets file lives at `/etc/gitlab/gitlab-secrets.json`, and the docs state that it contains the database encryptionEncryption🛡️The process of converting data into a coded format that can only be read with the correct decryption key. key. If you lose it, the application cannot decrypt any encrypted values in the database. The corollary is just as true: if an attacker reads it, they can.

GitLab's troubleshooting guide for a lost secrets file enumerates what depends on that key. CI/CD variables. Runner authentication tokens. Deploy tokens. Webhook secrets. Integration credentials for external services. Project mirroring credentials. Two-factor authentication seeds. Each of those is a credential to something outside GitLab: a cloud account, a container registry, a production deployment target, a chat system, another Git host.

A file read that returns the secrets file, combined with a read of the database or a database backup, therefore yields the plaintext of every secret the platform was trusted to hold. That is not an information leak. It is a wholesale credential theft with a single request. The explainer How Path TraversalPath Traversal🛡️A web vulnerability (CWE-22) where user-supplied input in a file path escapes the directory the application intended to serve from, typically via parent-directory references, letting an attacker read or write files elsewhere on the server. Bugs Let Attackers Read Files Outside the Web Root covers the mechanics of how such a read happens; this piece is about why the consequences are so disproportionate.

From Credentials to Code Execution

Even without the database, the secrets file and the main configuration file give an attacker a map. GitLab's documentation lists both `/etc/gitlab/gitlab.rb` and the secrets file as the minimum that must be backed up, because together they describe how the instance is wired: database location, external service endpoints, object storage settings, and the keys that authenticate to them.

From there, the attacker's path runs through the pipeline. watchTowr's analysis of the GitLab bug named the outcome plainly: access to source code, CI/CD secrets, credentials, and the ability to inject code into build pipelines. Runner tokens let an attacker register a malicious runner that receives real jobs. CI/CD variables usually contain cloud credentials that pipelines use to deploy. Deploy tokens grant registry access. Any one of those turns a read into a write somewhere downstream, and a write into a build pipeline is code execution on every system that pipeline touches.

This is the mechanism behind most supply-chain incidents that originate at a source-control server. The attacker rarely needs a remote code execution bug on the Git host. They need a credential the Git host was storing, and a build system that trusts it.

Why Vulnerability Scoring Undersells It

CVSS captures some of this. The vector for CVE-2026-85706 includes a changed scope, which reflects that the impact extends beyond the vulnerable component. But the score is a property of the bug, not the deployment, and it cannot express how many other systems a given GitLab instance holds keys for.

That is the gap teams should close in their own risk models. A file-read bug on a marketing site and a file-read bug on the CI/CD platform have the same CWE and might have the same CVSS. They are not the same risk. The second one should be triaged as a potential compromise of every environment the platform deploys to, and the incident response plan should start from that assumption rather than from the bug's technical description.

The practical implication is that developer infrastructure belongs in the same tier as domain controllers and identity providers. It should have the same patch urgency, the same monitoring, and the same restrictions on who can reach it. The site's earlier argument for treating AI infrastructure as privileged infrastructure applies here for the same reason: any system that brokers credentials to other systems is a concentration of trust, and trust concentrations are what attackers look for.

What Follows a Confirmed or Suspected Read

If your GitLab logs show a successful request to the vulnerable commits endpoint, or if the logs do not go back far enough to rule one out, the response is credential rotation at the scale the secrets file implies. GitLab's troubleshooting documentation for a lost secrets file is a useful map of the blast radiusBlast Radius🛡️The full set of systems, data, and access an attacker can reach after compromising a given asset. Ranking assets by blast radius rather than by how exposed they are pushes high-reach systems like a firewall management console to the top of the priority list., because it lists every table and feature that depends on the encryption key. Rotation means:

  • Regenerating the secrets file and re-encrypting what depends on it, following GitLab's documented procedure rather than improvising.
  • Resetting every CI/CD variable at the source: the cloud accounts, registries, and services those variables authenticate to, not just the values stored in GitLab.
  • Re-registering runners with new tokens, and auditing the runner list for registrations you do not recognize.
  • Rotating deploy tokens, webhook secrets, and integration credentials, and checking the receiving systems for activity during the exposure window.
  • Reviewing recent pipeline runs and merged changes for anything that was not authored by a known person.

This is a multi-day effort for a mid-sized organization. The general sequencing is covered in How to Rotate Every Secret After a Server Compromise. The GitLab-specific lesson is that the list is longer than most teams' inventories, because the platform stores credentials on behalf of every project, and project owners rarely know what their pipelines have accumulated.

Reducing the Damage Before the Next Bug

There will be another unauthenticated bug in a developer platform. GitLab alone had two critical flaws exploited within days of disclosure in the space of a month in 2026. The controls that limit the damage are structural, not reactive:

  • Keep long-lived cloud credentials out of CI/CD variables. Use short-lived, identity-federated credentials that a pipeline obtains at run time, so a stolen variable expires quickly and can be traced to a job.
  • Scope every token to the minimum it needs. A deploy token that can only pull one image is a much smaller prize than an account key that can administer the project.
  • Minimize the anonymous surface. Restricting public projects, described in How to Lock Down Public Projects on Self-Managed GitLab, would have narrowed the precondition watchTowr identified for the September flaw.
  • Store backups of the secrets file somewhere the application user cannot read, so a traversal bug in the application cannot reach both the key and the ciphertext.
  • Log API requests with source address and user identity, retain them long enough to cover a realistic detection lag, and alert on anonymous requests to endpoints that should never answer anonymously.

None of these prevent the next CVE. They change what an attacker gets when they exploitExploit🛡️Code or technique that takes advantage of a vulnerability to cause unintended behavior, such as gaining unauthorized access. it. A file read against a platform that stores only short-lived, tightly scoped credentials is an incident. A file read against a platform that stores the master key to production is a breach.