By Editorial standards

GitLab CVE-2026-85706: The NC Server You Forgot About

A CVSS 10 GitLab flaw let strangers read files off code servers, and attackers used it. Is a forgotten one hiding in your NC plant? Call (336) 886-3282.

Cover Image for GitLab CVE-2026-85706: The NC Server You Forgot About

TL;DR: In some North Carolina plants a computer holds software somebody wrote for you, and the owner may not know it's there. On September 10, 2026 GitLab patched a flaw in that kind of server, scored 10.0 out of 10, letting a stranger with no account read files off it. GitLab's own detection guidance says public scanning for it has been widespread since August. CISA added it to the federal exploited list on September 11, with a September 14 deadline, flagged as a case where agencies must patch and check for prior compromise. If yours ran an affected version while facing the internet, the upgrade alone doesn't close it out. Unsure whether you have one? Call (336) 886-3282.

What should I do about this today?

Forward this to whoever runs your network and any integrator maintaining your equipment:

Do we have a GitLab server anywhere on our network, including any machine you maintain on our behalf? If yes, I need three things in writing: the version number, whether it is reachable from the internet, and the date it was patched for CVE-2026-85706.

Two "no" answers are a start, not an all-clear: nobody speaks for a server left by a departed developer, or one that came with a company you bought. Back it with a software inventory: VMs, containers and packages on every host, hypervisor and NAS. Then a full TCP sweep, all ports, kept off the plant VLANs: NIST warns active scans may cause device instability on OT networks. No inventory to check, or nobody who can answer? Call us at (336) 886-3282.

Do you even have one?

Most owners would say no, and some of them are wrong. GitLab is where software gets stored and worked on, and at a company that doesn't consider itself one it rarely arrives through IT. Four ways one ends up in a plant:

  1. The one in-house developer. The guy who wrote your label printing stood it up on a spare server and updates it when something breaks, the pattern that lands a box in this flaw's range.
  2. An automation or machine-vision integrator. The outfit that commissioned a line left a box on your network to hold its code.
  3. An embedded product team. If you ship anything with a chip in it, the firmware lives somewhere, increasingly under EU reporting rules NC exporters now face.
  4. An acquisition. You bought a company in Hickory or Lexington and inherited its server room, uncatalogued.

Key takeaway: Nobody patches a server that isn't on anybody's list.

What does CVE-2026-85706 actually let someone do?

Read files off the server without logging in. GitLab's patch release calls it a path traversal issue in the repository commits API, scored CVSS 10.0, needing network access, no privileges, no user interaction.

Read the vector before you file this as a confidentiality problem. GitLab scored it C:H/I:H: integrity High, and that is where the 10.0 comes from, since the same vector with no integrity impact scores 8.6. GitLab's text says read; its score says more. So unexplained commits and .gitlab-ci.yml changes since August are in scope, not only leaked secrets, and a build pipeline that deploys to your floor is the thing to check first.

Two things decide how hard you push:

  • The affected range starts higher than you'd guess. From 18.7 before 18.11.12, 19.0 before 19.0.9, 19.1 before 19.1.8, 19.2 before 19.2.6 and 19.3 before 19.3.2. GitLab 18.7 shipped December 18, 2025, so an ancient box sits below the floor while a reasonably maintained one probably doesn't. Ancient isn't safe either: the October 21 flaw reaches back to 7.0.
  • There's a precondition, and it cuts both ways. watchTowr told The Hacker News that exploitation needs at least one public project. GitLab's advisory says only "under certain conditions," so an all-private server is probably a harder target. Open sign-up may let a stranger create one, so don't count on all-private.

Will fixing this stop my line?

Almost never. A GitLab server stores code, not the machine running your press. Two exceptions: a build that deploys to something live (a label printer feed, an MES dashboard) breaks when its credentials are revoked, and a box doubling as a license server or jump host drops that connection when isolated or rebooted. Then there is the upgrade window. For single-node instances GitLab's patch notes say "This patch will cause downtime during the upgrade," so expect it down at each required stop, with every pipeline it drives.

Whose server is it, if the integrator put it there?

The answer sits in a contract nobody has read since signing. Don't patch it unilaterally: their software may be pinned to versions they chose. Tell them in writing; the risk lands on you whatever the asset tag says, and a dated written reply is what you hand your insurer.

If the box isn't reachable, a week of silence from them is itself the finding. If it is reachable, a week is far too long against a three-day federal clock: check what rides on it first (their remote support, runners, webhooks), then cut its path the same day and escalate in parallel.

Why does the federal standard want more than a patch?

Patching a machine already read leaves behind whatever the reader took. CISA added CVE-2026-85706 to its exploited list on September 11, 2026, and the KEV catalog entry carries a September 14 remediation date and a forensic triage flag under Binding Operational Directive 26-04.

BOD 26-04, issued June 10, 2026, sorts exploited flaws by four things: is the asset publicly exposed, is it on KEV, can the exploit be automated, does it yield partial or total control. The worst combination gets a three-day clock plus a requirement to check the machine for evidence of prior compromise. This CVE landed there.

Agencies are held to that by directive; a 70-person shop in Thomasville by nothing. This reads files, but those files hold the database password and the keys that sign sessions and decrypt stored secrets. GitLab warns a stolen secret key base enables "session and token forgery," so you can't assume they stopped at reading.

If it ran an affected version, from August (or from first running 18.7+, if later) until you patchedOdds it was touchedWhat to do, in order
Not internet-reachable, logs cover the whole window, no hitLowCopy logs off, patch within days, verify it truly isn't reachable
Not reachable, but a hit in the logsTreat as touchedSomeone inside sent it. Copy logs, cut access, rotate and audit (step 3), patch, widen the search
Reachable, every project private, sign-up closedUncertainCopy logs, cut exposure, hunt. If the logs can't rule a read out, rotate before patching (our call). Patch
Reachable, a public project or open sign-upTreat as touchedCopy logs, cut exposure, rotate and audit (step 3), patch, check commits and CI config against known authors
Logs don't cover the whole window, or you can't reconstruct itUnknownTreat it as reachable
You can't answer the rows aboveUnknownFind the server. That's this week's whole job.

If your answer is the bottom row, you're not alone. Our managed IT team can help. Call (336) 886-3282.

How would you know whether yours was read?

Look in the logs. watchTowr tells defenders to hunt for POST requests to /api/v4/projects/{id}/repository/commits/ carrying file.path parameters. Two things matter more than that.

Keep and search two logs. gitlab_access.log records the full request line, query string included (GitLab's nginx config masks only token parameters), but never the POST body: a file.path sent in the query string shows there, a multipart one doesn't. /var/log/gitlab/gitlab-rails/api_json.log records API requests as JSON with a params array, which is where GitLab's own rules look.

The endpoint alone proves nothing. That route is how GitLab's create-commit API normally works, and its documented field file_path is easily confused with file.path. GitLab's own detection rules say what counts:

  • Either parameter, either API. file.path and its sibling metadata.path, on the repository commits API and the repository files API.
  • Any value outside Workhorse's temp directories. Legitimate clients "never set file.path to an absolute host path", so /etc/passwd or a gitlab.yml path is a hit. Don't grep only for ../: GitLab's sample attacks use plain absolute paths.
  • Bypass tricks. Public exploits use "a trailing-slash bypass and percent-encoding of the route and parameter" (%63ommits, file%2epath), so detection should not depend on the literal route. GitLab's rule also greps api_json.log for invalid %-encoding as a sign the encoding bypass was processed.

GitLab treats "any status other than 400" from the same anonymous caller as a read that "may have been served," and a 2xx as confirmed. Authentication is context, not proof: GitLab notes a low-privileged user can attempt the same request, so never clear a hit because it came from a valid session.

Two more things:

  • Hunt back to August. GitLab's rules say public scanning "has been widespread since August, so historical hunting should cover that window." A box on 18.7 or later since December 2025 may have been hit before that.
  • Retention counts copies, not days. GitLab's defaults rotate daily keeping 30 files, about a month, so on defaults they may no longer reach August. Copy them off first, and pull older copies from backups if you have them.

If the logs are gone and the box was exposed, our recommendation is to assume the secrets are known and treat it as a confirmed read.

What should we do if we find one?

Four steps, in this order:

  1. Copy api_json.log and gitlab_access.log off the box before they roll over.
  2. Cut its internet exposure. watchTowr says to patch "or remove public access." Check first what rides on it.
  3. If a read is confirmed, rotate now, scoped by what was requested. GitLab's rule says to "Read the requested path first," escalate "immediately" and rotate the exposed credentials "rather than waiting for the upgrade": the secret key base, the database credentials, and any object storage, SMTP or LDAP credentials in gitlab.yml. It adds: "Audit access to any external services whose credentials were exposed across the exposure window." Back up gitlab-secrets.json first, keep the original and never regenerate it wholesale: GitLab warns that if its column encryption key is lost, it can't decrypt CI/CD variables, runner authentication, integrations or webhooks. The rest is our recommendation, not GitLab's:
    • A read you can't rule out: treat it as confirmed.
    • secrets.yml or gitlab-secrets.json: GitLab warns this enables "session and token forgery and decryption of stored CI/CD variables and 2FA data." Rotate CI/CD variable values, re-enroll 2FA, and audit the window for new admins, access tokens (personal, project, group), deploy keys and tokens, account SSH keys, OAuth apps, webhooks, runner registrations and CI variable edits.
    • /proc/<pid>/environ: GitLab notes process environments "frequently carry secrets and tokens." Rotate every secret held there; on Docker that includes passwords and storage keys set in GITLAB_OMNIBUS_CONFIG.
    • Private uploads under /uploads/@hashed/ or repository data: a data exposure, not only a credential one. Bring in counsel.
    • /.ssh/, id_rsa or other host files: watchTowr reported attackers dumping "system SSH configurations" and said that "may allow" them to "gain access to the host under the right conditions." Check the host's SSH and auth logs, rotate its SSH keys and passwords, and rebuild at any sign of shell access.
  4. Patch to the newest release on your line: as of October 23, 19.5.1, 19.4.3 or 19.3.6, which also close the October 21 flaw. GitLab also backported to 18.11.13, 19.0.10, 19.1.9 and 19.2.9, beyond its normal policy of the current release and the previous two. Where one of those is a single hop, it can go in as early as step 2, without delaying step 3.

The rest is judgement, not a checklist. The upgrade is not a single hop: GitLab enforces required stop versions at 18.2, 18.5, 18.8, 18.11, 19.2 and 19.5, and no 18.7 to 18.10 line got the backport, so a box on 18.7 still drains background migrations at 18.8, still vulnerable, before it reaches 18.11.13. Keep exposure cut throughout. Closing an exposure path can lock you out of the machine you still have to patch, because on an integrator-built server the tunnel is often the only way in.

That judgement is the part to hand off. We do this work across the Triad. Call (336) 886-3282.

What if we use GitLab.com instead of our own server?

Then it isn't yours to fix. For this CVE, GitLab states that GitLab.com is already running the patched version and GitLab Dedicated customers need take no action.

Want a second set of eyes on what's running in your building? Preferred Data Corporation has served clients from High Point since 1987: on site within 200 miles, and remotely for clients across the US and around the world. Call (336) 886-3282 or contact us.

Frequently Asked Questions

Is CVE-2026-85706 a zero-day?

The sources don't settle it. GitLab shipped the fix on September 10, but its own detection rules say public scanning for this CVE "has been widespread since August." CISA listed it on September 11 "based on evidence of active exploitation," and watchTowr later reported successful exploitation. Don't assume attacks began with the patch: hunt back to August.

Ours is behind the firewall. Do we still need to move?

Yes, within days rather than next quarter: an inside read is still serious, and October 21's release fixes a separate CVSS 10.0 code-execution flaw. The three-day federal clock is for publicly exposed assets, so it is not a weekend emergency. The urgent piece is proving that belief, from outside your network rather than from the rule list.

How long does this take?

Finding out whether you have one comes first; with no server, that is the whole job. Past that, the schedule depends on how many required stops lie ahead and how many systems those credentials reach.

Does our cyber insurance care?

Expect it to. A dated ticket showing discovery, containment, rotation and patch answers a renewal question better than a yes. More in our Q4 cyber insurance renewals post.

We don't write software. Why is this in my inbox?

Because "we don't write software" and "no server here holds code" are different statements. The first is usually true at an NC manufacturer; the second often isn't, and that gap is where this class of incident lives, as the Telerik exposure in vendor-built portals did in September.