CVE-2020-15525
Description
GitLab EE 11.3 through 13.1.2 has Incorrect Access Control because of the Maven package upload endpoint.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
GitLab EE 11.3–13.1.2 had an access control flaw in the Maven package upload endpoint, allowing directory traversal via Workhorse bypass.
Vulnerability
GitLab EE versions 11.3 through 13.1.2 contain an incorrect access control vulnerability in the Maven package upload endpoint. The Workhorse reverse proxy interprets encoded URL path segments (e.g., %2f) as literal slashes, allowing an attacker to craft a path like 0040%2fpackages%2fmaven that bypasses Workhorse’s route authorization and reaches the Rails backend. The vulnerable route matches v4/projects/[0-9]+/packages/maven/, and the attack uses file.path or file.remote_id parameters to read arbitrary files from the server’s /tmp directory or from object storage [1].
Exploitation
An attacker needs a valid GitLab API private token and a project ID. They create a subgroup and project with a path crafted to match a different project’s numeric ID followed by /packages/maven (e.g., 0040/packages/maven for project ID 40). The attacker sends a PUT request to /api/v4/projects/0040%2fpackages%2fmaven/package/?file.path=../../../../../../../../../../../../etc/passwd (or file.remote_id for object storage). A 500 response indicates the file does not exist; a 400 response confirms the file exists, enabling file enumeration [1].
Impact
Successful exploitation allows an attacker with a valid API token to enumerate and read arbitrary files on the GitLab server’s filesystem (via path traversal) or in object storage. This leads to information disclosure of sensitive data such as system configuration files (e.g., /etc/passwd) and potentially other stored artifacts. No authentication bypass is required beyond having a valid token; the attack abuses the project path encoding confusion to escalate read access [1].
Mitigation
The vulnerability was fixed in GitLab EE version 13.1.3, released on 2020-07-06 [3]. Users should upgrade to 13.1.3 or later. No workaround is available for versions prior to the fix. The issue is also addressed in the related HackerOne report [1] and GitLab issue tracker.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
3- GitLab/GitLab EEdescription
- Range: >=11.3, <=13.1.2
Patches
0No patches discovered yet.
Vulnerability mechanics
Root cause
"Workhorse does not decode URL-encoded path separators (%2f) before route matching, allowing an attacker to bypass the upload authorization handler and reach the Rails API directly with arbitrary file.path or file.remote_id parameters."
Attack vector
An attacker creates a project whose path mimics a numeric project ID followed by `%2fpackages%2fmaven` (e.g., `0040/packages/maven`). When a PUT request is sent to `/api/v4/projects/0040%2fpackages%2fmaven/package/` with query parameters `file.path` or `file.remote_id`, Workhorse sees the URL-encoded slashes as part of the project path rather than route separators, so it does not apply the upload body handler. The request reaches the Rails backend, which decodes the path and processes the `file.path` parameter, allowing an attacker to read arbitrary files on the server (e.g., `/etc/passwd`) or enumerate objects in object storage [ref_id=1]. A 500 response indicates the file does not exist; a 400 response indicates it does [ref_id=1].
Affected code
The vulnerability lies in the Maven package upload endpoint at `/api/v4/projects/[0-9]+/packages/maven/`. The Workhorse reverse proxy uses route matching that does not decode `%2f` before checking the URL pattern, so a crafted path like `0040%2fpackages%2fmaven` bypasses the Workhorse authorization check and reaches the Rails application directly [ref_id=1].
What the fix does
The advisory does not include a patch diff, but the issue references a similar previously patched vulnerability (issue #209080) and describes the root cause: Workhorse's route matching in `internal/upstream/routes.go` does not decode `%2f` before comparing the URL path against the API pattern. The fix would require Workhorse to normalize URL-encoded path separators before route matching, or to validate that the `file.path` and `file.remote_id` parameters cannot reference arbitrary paths outside the intended upload scope [ref_id=1].
Preconditions
- authAttacker must have a valid GitLab account with a Private-Token for API access
- inputAttacker must create a project whose path contains the target project ID followed by '/packages/maven'
- configTarget GitLab instance must be version 11.3 through 13.1.2
Reproduction
1. Create a project and note its ID (e.g., 40). 2. Create a subgroup and project with the path `0040/packages/maven`. 3. Send a PUT request to `/api/v4/projects/0040%2fpackages%2fmaven/package/?file.path=../../../../../../../../../../../../etc/passwd` with a `Private-Token` header. 4. A 500 response means the file does not exist; a 400 response means it exists [ref_id=1].
Generated on May 25, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3- about.gitlab.com/releases/2020/07/06/critical-security-release-gitlab-13-1-3-released/mitrex_refsource_CONFIRM
- about.gitlab.com/releases/categories/releases/mitrex_refsource_MISC
- gitlab.com/gitlab-org/gitlab/-/issues/225259mitrex_refsource_MISC
News mentions
0No linked articles in our index yet.