Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-85706 — Python PoC exploiting CVE-2026-85706, an unauthenticated path traversal and arbitrary file read in GitLab CE/EE via the create-commit endpoint, with file-read oracle. | Kitploit
Tools/GitHubGitHub/brigadeops32/cve-2026-85706
Vulnerability ScannersVulnerability AnalysisExploitationWeb Application ExploitationData ExfiltrationInformation GatheringWeb SecurityPenetration Testing
GitHubbrigadeops32/cve-2026-85706

CVE-2026-85706

Python PoC exploiting CVE-2026-85706, an unauthenticated path traversal and arbitrary file read in GitLab CE/EE via the create-commit endpoint, with file-read oracle.

7h 40m agoNot yet reviewed
View Repository

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-85706

Unauthenticated path traversal / arbitrary file read in GitLab CE and EE. CVSS 10.0. Verified against a self-managed 19.3.1 instance in a local lab.

Affected

GitLab CE/EE:

  • 18.7 up to 19.1.7
  • 19.2.0 up to 19.2.5
  • 19.3.0 up to 19.3.1

Precondition: the instance has at least one public project. Any real project id works. No account or token needed.

How it works

The create-commit endpoint POST /api/v4/projects/:id/repository/commits accepts large file bodies, so Workhorse buffers the request body to disk and injects file.path / file.size metadata for Rails to read back. Four mistakes line up:

  1. The route only checks require_gitlab_workhorse! at entry. The real authenticate! sits behind authorize_push_to_branch!, which runs after the file read.
  • file_params_from_body_upload takes file.path and file.size straight from request parameters, so File.read(file_path) follows any absolute path you supply.
  • Workhorse's body-upload intercept matches .../repository/commits\z. Adding a trailing slash misses that route and falls through to the signed reverse proxy, which forwards the raw body with a valid JWT. The Workhorse check passes, Grape normalizes the slash, and the forged params survive.
  • With Content-Type: application/x-www-form-urlencoded the file content is parsed by Rack::Utils.parse_nested_query. An illegal % sequence raises ArgumentError: invalid %-encoding (<component>) and the 400 response echoes that component verbatim.
  • The read runs as the git user. Content comes back only if the file contains an illegal % sequence; otherwise you still get a clean existence and readability oracle:

    ResponseMeaning
    400 local file not presentfile does not exist
    500exists, not readable by git
    401exists and readable, no illegal %, nothing echoed
    400 invalid %-encoding (...)readable, component echoed

    Files that reliably echo on a default omnibus install: gitlab.yml (header comment hits 95% early), CI job logs and artifacts, uploaded attachments, and database.yml on deployments with an external database.

    Usage

    root@kitploit:~
    python3 exploit.py -t http://target:8080                 # reads gitlab.yml
    python3 exploit.py -t http://target:8080 -f /etc/passwd
    python3 exploit.py -t http://target:8080 -p 3 -o out.txt
    

    No dependencies, stdlib only.

    Verified output

    Against gitlab-ce 19.3.1 in docker, zero credentials:

    root@kitploit:~
    $ python3 exploit.py -t http://127.0.0.1:8929
    [*] HTTP 400 | leaked
    [+] leaked content of /var/opt/gitlab/gitlab-rails/etc/gitlab.yml:
    ------------------------------------------------------------
    =========================
    
      ## GitLab settings
      gitlab:
        ## Web server settings (note: host is the FQDN, do not include http://)
        host: localhost
        port: 8929
        https: false
        ...
    ------------------------------------------------------------
    

    Oracle spot checks from the same run:

    root@kitploit:~
    /etc/passwd        -> 401 (readable, no echo)
    /etc/shadow        -> 500 (exists, permission denied)
    /etc/nonexistent   -> 400 local file not present
    

    Disclaimer

    For authorized security testing and research only. Do not use against systems you do not own or have explicit permission to test.

    Download Tool