-
This is great insight! Thanks for your investigation and sharing the result with me. Really appreciated!
OneDev clones the repository into local file system and mounts into container instead of cloning directly inside container in order not to require user supplied image (to build/test project etc) to contain git clone tools, which can be very cubersome.
As long as OneDev server removes the possibility of pushing to file based repository on server file system (currently only exists in push repository step), vulnerabilities like this should no longer be possible.
What do you think?
PS: Curious how you've managed to find this vulnerability (and previous vulnerabilty for pull repository step), as these requires some internal knowledge of OneDev. There are other security researchers reporting issues before, but most of them are related to deserialization from untrusted source which is a common pattern.
-
Also this vulnerability should no longer be possible with previous vulnerability fix which verified http/https protocol of remote url when runs the job:
https://code.onedev.io/onedev/server/~commits/bccaf576b5684bb8323c1b685c6610f7b3fca0e2
-
Hi,
First of all, I’m glad to assist OneDev in addressing this security issue. Let me respond to these questions in order:
-
The fix you’ve implemented is indeed effective. The exploitation method requires multiple steps to work in conjunction, so if any one of these steps fails, the entire exploitation chain is ineffective. Therefore, restricting the repository protocol to HTTP/HTTPS should work fine.
-
I am indeed a security researcher and am currently preparing to submit this idea to an industry conference. Since they require vulnerabilities to be disclosed to the vendor 90 days before the conference starts, I’m working hard to draft the issue :). As for how I discovered it, I found similar vulnerabilities in other products and wondered whether this exploitation technique could be extended to other systems. Unfortunately, OneDev has a similar implementation issue XD. I hope this helps in fixing the issue quickly.
Additionally, since this technique hasn’t been publicly disclosed yet (if my conference submission is successful, it will be revealed next year), and because the current fix should already mitigate the vulnerability, I kindly ask you to keep this issue private for now. Thank you!
-
-
Additionally, since this technique hasn’t been publicly disclosed yet (if my conference submission is successful, it will be revealed next year), and because the current fix should already mitigate the vulnerability, I kindly ask you to keep this issue private for now. Thank you!
Sure. I will keep it secret until you discloses this.
-
Previous Value Current Value Open
Closed
-
Fixed in build OD-5797
-
Hi, Since the vulnerability can now be disclosed, I’ve updated the issue status from confidential to open.
-
Previous Value Current Value true
false
| Type |
Security Vulnerability
|
| Priority |
Major
|
| Assignee | |
| Labels |
No labels
|
Summary
In Onedev's CI/CD jobs, job like checkout code and push to remote allow operations such as checkout and push commands based on the git repository.
Notably, when Onedev performs checkout operations, it leaves the git repository content in a temporary local directory. This means any content within the git repository will land in the local file system where the onedev server does.
This introduces a new attack surface called the server push attack. We know that git repositories have a hooks mechanism, divided into two types: client hooks and server hooks. Here, we focus on server hooks. For instance, during a git push operation, the server-side git repository receives data and triggers the
pre-receivescript under.git/hooks.This creates an attack vector: If an attacker can create a git repository and have it land on the local file system, combined with workflows that push to the repository, the lack of validation for repository addresses on the server allows an attacker to exploit the
file://protocol to point to a malicious local repository. This triggers hooks scripts in the malicious repository, enabling command execution on the local machine.Since git repositories can contain bare repo content, the following vulnerabilities arise in Onedev's scenario:
These issues lead to RCE vulnerabilities.
Steps to Reproduce
Log in with code writer permissions for any project.
Import a malicious git repository prepared by the attacker, https://gitlab.com/demo621918/testrepo/- . The
exploitbranch of this repository contains a subdirectory namedevilgitdirectory, structured as a git bare repo. Thehooksfolder in this directory includes apre-receivescript that, when triggered, executes the commandtouch /tmp/pwned.exploitbranch (important!) in this repository. Use the.onedev-buildspec.ymlfile to create the following jobs. This job represents a checkout operation on the malicious repository, followed by a step that executes the commandsleep 30in the containerubuntu:latest. Since the job does not complete, the temporary directory will persist instead of being deleted. The directory structure will be/opt/onedev/temp/server/onedev-build-{REPO_NUM}-{JOB_NUM}/workspace/.opt/onedev/temp/server/onedev-build-3-1/workspace/evilgitdirectory/. Create another job to push to this repository, triggering the hooks in the previous malicious repository. When creating this new job, calculate the accurate values foronedev-build-3-1, where 3 represents the project number in Onedev, and 1 is the build number of the checkout job. For instance, if the project is the third code repository and the first checkout job is being executed, use the following.onedev-buildspec.ymlin another project or the current one:sleep 30phase, ensuring the temporary directory persists. Then execute the second job to push to the first repository, triggering the server push and achieving RCE.