top of page

Hunt the commits POST that reads the GitLab box

Writer: Inception Security
Inception Security
11 hours ago
7 min read


The request still sitting in your proxy, WAF, or GitLab access log is not a closed patch card. It is an HTTP POST to /api/v4/projects/{id}/repository/commits or the trailing-slash form /api/v4/projects/{id}/repository/commits/ that carries a

file.path or file.Path parameter from a client you did not expect. GitLab patched CVE-2026-85706 on 10 September 2026. That upgrade does not tell you whether someone already asked the box to read /etc/gitlab or other secrets the GitLab process can see before you upgraded.


This hunt shop is not a second CVSS recap and it is not an exploit recipe. CVE-2026-85706 is a path traversal on the repository commits API. GitLab describes improper path confinement plus missing authentication enforcement. Under certain conditions an unauthenticated caller can read arbitrary files the GitLab server process can reach. watchTowr and The Hacker News state the practical precondition: the instance needs at least one public project. watchTowr saw in-the-wild probes from 06:00 UTC on 11 September 2026. CISA added the CVE to KEV the same day, with a federal due date of 14 September 2026. The huntable shape is the commits POST and those file.path / file.Path fields.


How the GitLab commits-API read works


Name the chain the way triage already thinks: what each stage does and what it looks like in logs. Do not reconstruct a working request body or gadget recipe.


Stage A. Precondition


The instance has at least one public project. That is the condition watchTowr and The Hacker News call out before an unauthenticated caller can use this path. Hunt your self-managed GitLab public-project inventory first. An internet-facing CE or EE box with a public project is the exposure class that matters here.


Stage B. Unauthenticated commits API


The attacker sends an unauthenticated or anonymous POST to the repository commits API. GitLab's root cause language is improper path confinement combined with missing authentication enforcement on that endpoint. Hunt unexpected POST traffic to /api/v4/projects/*/repository/commits and the trailing-slash form, especially from external or unknown clients with no session or token you recognize.


Stage C. File read


Successful abuse returns file contents the GitLab process should never have handed out. Public reporting describes configs, secrets, credentials, logs, and other server-side data the process can read. Hunt successful 200 responses on suspicious commits POST requests that mention file.path or file.Path. Pair those hits with a secret-rotation review for anything that process could touch.


Stage D. Why attackers care


Jake Knott at watchTowr put the appeal plainly: unauthorized access unlocks source code, CI/CD secrets, credentials, and the ability to inject into build pipelines and poison anything downstream. After a file-read hit, pivot to token and runner abuse, unexpected CI/CD variable changes, and pipeline jobs you did not authorize.


Timeline in one beat: GitLab shipped patched CE/EE builds 19.1.8 / 19.2.6 / 19.3.2 on 10 September 2026 for versions from 18.7 before those builds. watchTowr probes began 06:00 UTC on 11 September. CISA KEV landed 11 September with a 14 September due date. OpenCVE shows the CVE record published overnight on 12 September. The same patch batch also ships critical GraphQL Duo Chat deserialization CVE-2026-87719 (CVSS 9.9, EE, authenticated Duo Chat). Treat that as an optional side dig, not the lead. For context only, GitLab's prior max path traversal CVE-2023-2825 (uploads / nested public projects) is a reminder that path confinement keeps biting this platform. Do not turn this post into a CVE museum. Same-week GraphQL code injection CVE-2026-19478 is the other recent critical Knott referenced; keep this draft on the commits API oracle.


Risk: what this means for the company


Risk here is not the CVSS 10 sticker. Internet-facing self-managed GitLab is a crown-jewel SCM and CI plane. An arbitrary file read can expose tokens, database credentials, SSH keys, and configs the GitLab process can touch. Those secrets unlock source theft and pipeline injection. Downstream build consumers trust what GitLab ships. The practical risk is one unauthenticated POST while a public project exists, then quiet use of whatever leaked.


GitLab.com is already patched. GitLab Dedicated needs no customer action per the vendor. Self-managed CE and EE is the hunt surface. If the instance was reachable from the internet and unpatched during the window after disclosure, assume the commits API may already have been probed.


Mitigate GitLab commits-API risk


Concrete controls before the paste hunts.

Upgrade self-managed CE and EE to 19.1.8, 19.2.6, or 19.3.2 (or a later supported build on the correct branch). If you cannot patch today, restrict internet exposure to GitLab as temporary risk reduction. Horizon3 and vendor urgency treat network restriction as a bridge, not a substitute for the upgrade.


Inventory public projects on every self-managed instance. After a vulnerable internet-facing window, treat secrets the GitLab process could read as rotation candidates: personal and project tokens, runner tokens, deploy keys, database passwords, and related CI/CD credentials.


Review CI/CD variable changes and unexpected pipeline jobs since 10 September 2026. Document GitLab.com and Dedicated as out of scope for the audit when that matches your estate.


Clean-bill checklist


A quiet bill is more than "GitLab is current." Patching stops the next unauthenticated read. It does not erase a commits POST that already returned secrets, or a runner token that already moved.

  • Version is 19.1.8+, 19.2.6+, or 19.3.2+ on the correct branch

  • No unexplained POST to /api/v4/projects/*/repository/commits (or trailing-slash form) with file.path / file.Path since 10 September 2026 from internet or unknown clients

  • Public-project inventory reviewed on every self-managed instance

  • Secrets, tokens, deploy keys, and runners rotated if the instance was internet-reachable and unpatched during the window

  • Optional: Duo Chat / Advanced Search credential review if EE and CVE-2026-87719 is in scope

Anything short of that is still the commits POST that reads the GitLab box.


Hunt GitLab CVE-2026-85706


Paste these. Bound to the watchTowr, GitLab, The Hacker News, SecurityWeek, BleepingComputer, CISA, and OpenCVE artifacts above. Window starts at datetime(2026-09-10), matching the patch and disclosure day. Prefer proxy, WAF, GitLab access or production_json, and CDN logs over version strings alone. Do not paste a working exploit body. Do hunt the defender-safe fields and the watchTowr string: HTTP POST to /api/v4/projects/{id}/repository/commits/ URIs containing file.path or file.Path.

Hunt GitLab CVE-2026-85706 in KQL

Proxy / WAF:

// Proxy / WAF / CommonSecurityLog: commits API POST with file.path / file.Path
CommonSecurityLog
| where TimeGenerated >= datetime(2026-09-10)
| where RequestMethod =~ "POST"
| where RequestURL has "/repository/commits"
   or RequestURL has "/api/v4/projects/"
| where RequestURL has_any ("file.path", "file.Path")
   or Message has_any ("file.path", "file.Path")
   or AdditionalExtensions has_any ("file.path", "file.Path")
| project TimeGenerated, DeviceName, SourceIP, RequestMethod, RequestURL,
    DestinationHostName, Message, AdditionalExtensions

GitLab access / production_json:

// Custom GitLab access / production_json ingest (adjust table and field names)
GitLabAccessLogs
| where TimeGenerated >= datetime(2026-09-10)
| where Method =~ "POST" or method =~ "POST"
| where Path has "/repository/commits" or path has "/repository/commits"
   or Uri has "/api/v4/projects/" or uri has "/api/v4/projects/"
| where RawRequest has_any ("file.path", "file.Path")
   or QueryString has_any ("file.path", "file.Path")
   or Body has_any ("file.path", "file.Path")
| project TimeGenerated, SourceIP, Method, Path, Status, UserAgent, RawRequest
// watchTowr: POST /api/v4/projects/{id}/repository/commits/ with file.path / file.Path

Hunt GitLab CVE-2026-85706 in Falcon CQL

Raw message / proxy-shaped hits:

#event_simpleName=*
| timestamp>=#2026-09-10#
| (RawMessage=*/repository/commits* OR Message=*/repository/commits*
   OR RawMessage=*/api/v4/projects/* OR Message=*/api/v4/projects/*)
| (RawMessage=*file.path* OR Message=*file.path*
   OR RawMessage=*file.Path* OR Message=*file.Path*
   OR RawMessage=*POST* OR Message=*POST*)
| table timestamp, ComputerName, event_simpleName, LocalAddressIP4, RemoteAddressIP4,
    RawMessage, Message

GitLab hosts:

#event_simpleName=NetworkConnectIP4 OR #event_simpleName=DnsRequest OR #event_simpleName=*
| timestamp>=#2026-09-10#
| (aip=* OR ComputerName=*gitlab* OR aid=*)
| (RawMessage=*repository/commits* OR CommandLine=*repository/commits*
   OR ImageFileName=*gitlab* OR CommandLine=*gitlab*)
| table timestamp, ComputerName, ImageFileName, CommandLine, RawMessage,
    LocalAddressIP4, RemoteAddressIP4
// Pair Falcon-visible GitLab hosts with proxy hits on commits + file.path

Hunt GitLab CVE-2026-85706 in Splunk

Wide POST (proxy / WAF / web):

index=* (method=POST OR http_method=POST OR request_method=POST)
  ("/repository/commits" OR "/api/v4/projects/")
  ("file.path" OR "file.Path")
earliest=09/10/2026:00:00:00
| eval src_ip=coalesce(src_ip, src, clientip, client_ip)
| eval status=coalesce(status, http_status, status_code)
| eval uri=coalesce(uri, uri_path, url, request, http_uri)
| stats count values(status) as statuses values(user_agent) as uas
    values(uri) as uris by src_ip
| sort -count

GitLab / nginx / WAF:

index=gitlab OR sourcetype=*gitlab* OR sourcetype=*nginx* OR sourcetype=*waf*
  method=POST ("/repository/commits" OR "/api/v4/projects/")
  ("file.path" OR "file.Path")
earliest=09/10/2026:00:00:00
| timechart span=1h count by status

Hunt GitLab CVE-2026-85706 in Kibana

Discover / ES|QL:

// Discover / ES|QL-shaped filter since 2026-09-10
url.path: *repository/commits* AND http.request.method: POST
  AND (http.request.body.content: *file.path* OR http.request.body.content: *file.Path*
       OR url.query: *file.path* OR url.query: *file.Path*
       OR message: *file.path* OR message: *file.Path*)

Lens / visualize:

// Lens / visualize: first-seen since Sep 10 by source.ip and http.response.status_code
filters:
  - http.request.method: POST
  - url.path: *\/api\/v4\/projects\/*\/repository\/commits*
  - query_string: "file.path OR file.Path"
date histogram: @timestamp from 2026-09-10
terms: source.ip, url.path, http.response.status_code, user_agent.original

Sources

What This Means for Your Team


This case does not open on "patch GitLab and close the ticket." It opens when proxy, WAF, or GitLab access logs show an HTTP POST to /api/v4/projects/*/repository/commits (or the trailing-slash form) that carries file.path or file.Path from an unexpected client. CVE-2026-85706 is unauthenticated path traversal on the commits API when at least one public project exists. watchTowr saw probes from 06:00 UTC on 11 September 2026. CISA put it on KEV with a 14 September 2026 due date. A patched 19.1.8 / 19.2.6 / 19.3.2 build stops the next read. It does not tell you whether secrets the GitLab process could touch already walked out. If your hunts only watch the version string, you will miss the commits API oracle. Hunt those fields while the September window is still in scope.


Inception Protection


Inception Protection is Inception Security's MDR on the Defender and Sentinel stack you already pay for. For this GitLab chain we hunt proxy, WAF, and access logs for POST /api/v4/projects/*/repository/commits with file.path / file.Path, flag anonymous or external sources and 200 responses since 10 September 2026, and help you rotate tokens and runners on self-managed boxes that were internet-reachable before you landed 19.1.8 / 19.2.6 / 19.3.2.


Free Inception Foresight M365 Assessment


Want to see where your environment stands against GitLab commits-API traces like these, not just the version on the ticket? Grab our free Inception Foresight M365 Assessment. No strings. If this is useful, follow Inception Security on LinkedIn and @inceptionsec on X.

bg-map-white.png

INCEPTION SECURITY™

A cybersecurity company with in depth knowledge of the threat landscape and security controls.

NAVIGATION

GET IN TOUCH

© 2025 All Rights Reserved by INCEPTION SECURITY™ .

bottom of page