PoC Exploit for GitLab: An Authenticated User Gains Command Execution as git
Translated by a model; the original is in Russian.
Yuhang Wu, a researcher at depthfirst, has published a working proof-of-concept that allows commands to be executed as the git user on an unpatched self-managed GitLab 18.11.3 server. Kicking off the chain requires nothing more than an ordinary authenticated user: they commit two specially crafted Jupyter notebooks and request a diff of them. No admin privileges, no access to CI runners, no victim interaction, and no access to someone else's project are needed.
Where the root of the problem lies
The vulnerabilities lie not in GitLab itself, but in Oj — a high-performance JSON parser for Ruby with a large amount of native C code. The notebook renderer passes the contents of .ipynb files (that is, repository-controlled data) straight into Oj::Parser.usual.parse inside a long-lived Puma worker. That is how the attacker's data ends up in the parser's native state within the application process.
One bug allows control of a callback pointer, the other leaks an address from the heap — needed to narrow down the brute force when defeating ASLR. Oj stores nesting state in a fixed 1024-byte buffer but does not check for overflow: deeply nested arrays make it possible to corrupt adjacent parser state. Two lexicographically ordered files in a single diffs_stream request keep both stages inside one worker, which reuses the global Oj parser. The first file corrupts the pointer, the second parse invokes it — and through a build-specific sequence of gadgets it reaches system().
On a profiled installation with two workers, the brute force typically took five to ten minutes; for a wider range, the researchers estimated the time at one to two hours.
Who is affected
The targets are GitLab CE and EE versions 15.2.0–18.10.7, 18.11.0–18.11.4, and 19.0.0–19.0.1, as well as the Free, Premium, and Ultimate editions. The first fixed releases are 18.10.8, 18.11.5, and 19.0.2. Oj gems from 3.13.0 through 3.17.1 are vulnerable; the first release with both fixes is 3.17.3. Ruby itself is not affected.
Successful exploitation grants execution as git, and the real-world reach depends on the isolation of the deployment: source code, Rails secrets, service credentials, CI/CD data, and internal services reachable from the application may all be at risk. GitLab.com was patched back on June 10. Self-managed operators are advised to upgrade to a supported version; Helm and Operator users should check the GitLab version inside the Webservice image, not just the chart or operator version. Neither depthfirst nor GitLab offers a temporary workaround.
A curious detail: neither the depthfirst disclosure nor GitLab's June release notes provide CVE identifiers or CVSS scores for the two bugs in the chain. What's more, GitLab listed the Oj upgrade to 3.17.3 in the bug-fix section rather than in the security-fix table, and did not describe the RCE mechanism via notebook diffs at all. As of July 24, depthfirst has no information about attacks in the wild.
Source: The Hacker News
Comments
Sign in, to comment.