GitLab is a web-based platform for version control, CI/CD pipelines and collaboration on software development projects.
An arbitrary path traversal vulnerability has been recently reported in the GitLab Community Edition (CE) and Enterprise Edition (EE) affecting version 16.0.0. It is because of improper limitation of a pathname to a restricted directory. It has been assigned CVE-2023-2825. More details about CVE-2023-2825 can be found at NVD. It has a CVSS 3.1 score of 10.
This vulnerability enables an attacker to remotely access and read any file on the server without requiring authentication. The exploit occurs when a document is attached to a public project nested within five or more groups.
A patch was released by GitLab on May 20th, 2023 for CVE-2023-2825, which later became public. Several proof-of-concepts proving its exploitability appeared online.
In this blog, let’s take a close look at this vulnerability.
In our lab, we hosted GitLab version 16.0.0 on a Docker environment to recreate the attack scenario.
As per the NVD, “an unauthenticated malicious user can use a path traversal vulnerability to read arbitrary files on the server when an attachment exists in a public project nested within at least five groups.”
In analyzing this information, the vulnerable environment should encompass the following criteria:
- A minimum of five nested groups.
- A public project located within one of the nested groups.
- The presence of attachments within the project.
Nested groups are essential, and only the root user can create them. Therefore, to facilitate testing, they were created by logging in as the root user.
Reproducing the attack scenario:
The vulnerable GitLab instance was successfully launched:
When we attach a file to a GitLab issue, it triggers a POST request to /[repo]/uploads. This request generates a JSON response containing the file URL, which allows you to conveniently access the uploaded file.
The appearance of a public project is depicted as follows:
The occurrence of general file upload within project issues takes place in the following manner:
The process of a general file upload request and response occurs as follows:
The file URL follows the pattern /[repo]/uploads/[id]/[file], where [file] represents the name of the file. By replacing [file] with any desired file path, GitLab retrieves and returns the requested file.
However, GitLab overlooks the need to sanitize the file path, resulting in a path traversal vulnerability.
To successfully exploit this vulnerability, one must URL encode the forward slash (/) in the file path. GitLab interprets this as a value and internally decodes it. Failing to encode the forward slash will cause GitLab to treat it as part of the route, leading to unexpected behavior.
GET request with attack pattern:
- It starts with a GET request that includes more than five nested groups. These groups are like folders within folders, represented by paths such as ‘/HZS-1/HZS-2/HZS-3/HZS-4/HZS-5/HZS-6/HZS-7/HZS-8/HZS-9/HZS-10/HZS-11/’.
- Following the nested groups, the request includes a project name, an ‘uploads’ directory, and an ID. For example, the request might look like ‘CVE-2023-2825/uploads/33175514e5fe10daa61adfbd35c642ce/’.
- Understanding the Path Traversal String and Encoding: To navigate through various levels of the directory structure, a path traversal string is added to the request. This string is like a special code that tells the server to move up one level. In this case, the string ‘..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F’ is used. Note that the forward-slash in the string must be URL encoded, represented by ‘%2F’.
- Determining the Number of Path Traversal Strings:The number of path traversal strings required depends on the number of nested groups. To reach the desired level within the directory structure, the number of path traversal strings is equal to the number of nested groups plus one.
- Including a File from the Host Machine: Lastly, the request involves including a file from the host machine. For instance, the file ‘/etc/passwd’ is added as ‘%2Fetc%2Fpasswd’ in the request. It’s important to encode the forward-slash using URL encoding to ensure the server correctly interprets the request.
Executing the attack:
11 nested groups are created with random names,
A public project has been added within the 11th nested group.
This is how a packet capture of the complete attack looks like:
A sample file uploaded:
We can then fetch ‘/etc/passwd’ using directory traversal:
Conclusion and Remediation
The exploitation of CVE-2023-2825 can provide unauthorized users with access to files that are otherwise restricted. This issue is particularly concerning in the case of GitLab, as it could potentially expose crucial system files like ‘/etc/passwd’. If an attacker gains access to these files, they may be able to obtain valuable information such as user account details, which could then be used for additional unauthorized access or exploitation.
Juniper Networks’ NGFW SRX customers with an IDP license are protected against compromise of this vulnerability using the signature:
This signature is already part of IDP sigpack from #2470 and is part of the “Enterprise – Recommended” predefined attack group.
At the same time, those affected by CVE-2023-2825 should upgrade the Gitlab to the latest version, as advised by the vendor.