Safeguard
Vulnerability Analysis•

GitLab CVE-2026-85706: Unauthenticated File Read Now in CISA KEV

A CVSS 10.0 path traversal in GitLab's repository commits API lets anyone read server files, including gitlab-secrets.json. CISA added it to KEV on 11 September.

Safeguard Security Team
6 min read

On 10 September 2026 GitLab shipped a critical patch release for self-managed GitLab CE and EE. The top fix, CVE-2026-85706, lets an unauthenticated caller read arbitrary files from the GitLab server through the repository commits API. One day later, on 11 September, CISA added it to the Known Exploited Vulnerabilities catalog with a federal due date of 14 September.

GitLab scores it 10.0 under CVSS 3.1. The files an attacker wants are not source code. They are gitlab-secrets.json, secrets.yml and database.yml, which hold the keys that protect sessions, tokens, stored CI/CD variables and 2FA data.

What's affected

GitLab's advisory lists GitLab CE/EE, all deployment types:

BranchVulnerableFixed in
18.7 through 18.11before 18.11.1218.11.12
19.0before 19.0.919.0.9
19.1before 19.1.819.1.8
19.2before 19.2.619.2.6
19.3before 19.3.219.3.2

19.3.2, 19.2.6 and 19.1.8 came out on 10 September. GitLab backported the fix to 19.0.9 and 18.11.12 on 23 September, so older branches now have a supported path too. GitLab.com and GitLab Dedicated are already patched.

The bug was reported through HackerOne by the researcher s3ntago. GitLab's detection notes explain the mechanics. On multipart uploads, GitLab Workhorse buffers the body to a temp file and passes Rails a file.path parameter pointing at it. An attacker can supply their own file.path (or the sibling metadata.path) so Rails opens a host path instead. The parameter is reachable through POST /api/v4/projects/:id/repository/commits and the repository files API. GitLab says public exploits defeat route sanitization with a trailing slash and percent encoding, for example %63ommits for commits and file%2epath for file.path.

How to check if you're exposed

Start with the version. On an Omnibus install:

sudo gitlab-rake gitlab:env:info | grep -i "^GitLab information" -A2
# or
sudo cat /opt/gitlab/version-manifest.txt | head -1

Anything in the table above that is below its fixed build is vulnerable.

Then hunt. GitLab published three Sigma detections for this CVE, and all of them read api_json.log. The high signal pattern is an unauthenticated POST where the multipart params include an empty file part and a file.path or metadata.path value that points outside the Workhorse temp directories. A quick first pass on an Omnibus host:

sudo zcat -f /var/log/gitlab/gitlab-rails/api_json.log* \
  | grep -iE 'file(\.|%2e)path|metadata(\.|%2e)path' \
  | jq -c 'select(.method=="POST") | {time, status, remote_ip, ua, path, client: ."meta.client_id"}'

How to read the results, per GitLab's rule notes:

  • A file.path value naming gitlab.yml, secrets.yml, database.yml or gitlab-secrets.json is a targeted attempt.
  • A status of 400 is the expected rejection on a patched instance. Any other status from an anonymous ip/ client, especially a 2xx, should be treated as a possible served read.
  • Several distinct out of sandbox paths from one IP in a short window is the enumeration pattern. Attackers walk paths like /etc/passwd and /proc/self/environ before going for secrets.
  • metadata.path has no legitimate value outside the Workhorse scratch directory, so a single hit there is enough to investigate.

Match case insensitively. The percent encoded variants will slip past an exact string match.

What to do now

  1. Upgrade to 19.3.2, 19.2.6, 19.1.8, 19.0.9 or 18.11.12, whichever matches your branch. The release includes database migrations, so single node instances will see downtime while they run.
  2. If you can't upgrade today, restrict who can reach the instance's HTTP API at the network edge until you can. There is no vendor workaround in the advisory.
  3. Run the log search above across every retained api_json.log, not just the current file. Forward the logs to your SIEM if they aren't already and load GitLab's three Sigma rules.
  4. If you find a non 400 response to a secrets path, treat the instance as compromised. Rotate database credentials, any LDAP, SMTP and object storage credentials in gitlab.yml, and every CI/CD variable stored on the instance. An exposed secret key base means sessions and tokens can be forged, so plan to rotate it and force re-authentication.
  5. Review personal access tokens, deploy tokens and new admin accounts created since your exposure window opened.

Why it matters

A source control server is a credential vault that happens to also store code. This bug doesn't need an account, and the target files decrypt the CI/CD variables that hold cloud keys, registry tokens and signing material. One served read can turn into access to everything your pipelines touch.

The other lesson is how fast exploitation followed disclosure. The patch shipped on 10 September and CISA listed the CVE as exploited the next day. For self-managed platforms that sit on the internet, "next maintenance window" is not a patch plan.

Try it yourself

Pull a week of api_json.log from a non-production GitLab and run the jq filter above. Then send one harmless request with a file.path parameter that points at a temp file you created, and confirm your SIEM rule fires on it. If it doesn't, you have found the gap before an attacker did.

To see how a known exploited CVE flows through triage, assignment and closure, walk through this demo:

Click through it at your own pace, or open it full screen.

Quick check

Does CVE-2026-85706 require a GitLab account to exploit?

No. GitLab describes it as exploitable by an unauthenticated user, and its detections key on anonymous ip/ clients with no user attached.

Which log file shows exploitation attempts?

api_json.log. The multipart parts appear in the params array, so look for file.path or metadata.path values pointing at host paths outside the upload temp directories.

I'm on GitLab 18.10. Is there a fix for my branch?

GitLab lists all versions from 18.7 before 18.11.12 as affected. The oldest fixed build is 18.11.12, so an 18.10 instance needs to move to 18.11.12 or a newer supported release.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.