Full Report
Gogs is an open source solution for self-hosting source code with similar functionality to Github and Gitlab. Under the hood, Gogs users allow for pushing and pulling to Git repos over SSH via the Golang package golang.org/x/crypto/ssh for most complicated things. On top of this functionality, Gogs adds authorization checks. When interacting with the SSH server for git, there are two types of commands: env and shell requests. The env requests calls the env command to get ENV variables. Although, they protect against command injection they do NOT protect against the cousin argument injection. We can control arguments of the env command! Well, sort of. The actual code concatenates a key and value for the command with an equals sign with an empty string check on the values. So, we need an argument that will allow for the equals sign and be valid. While looking around, the flag --split-string can be used to have a proper command AND get command execution. So, RCE on the server via connecting via SSH has been completed! The actual exploitation requires a tricky scenario. First, SSH has to be enabled (meaning it is not default). Second, the attacker needs a valid SSH key or self registration needs to be turned on. Finally, the version of the env binaries matters, as the Alpine Linux version wasn't exploitable, for instance. They found three other vulnerabilities in the next blog post. The next argument injection was within the git diff command. By using the undocumented --output flag, we can open and close an arbitrary file. By forcing this into an error path, the file will be empty. This is where things get wild! If the .git/HEAD command is corrupted, then it will function as a bare repo. If the git repo is controlled, then we can add malicious configs (such as core.fsmonitior to get code execution on the next git command that is run. The next argument injection was in git tag. By specifying the --file flag on the command, the file will be used as the tag message. In a future command, just read the tag message for an arbitrary file read. This was not mentioned in the article but was included on their argument injection vectors site. The final vulnerability was simple file deletion - no directory traversal needed! By deleting the .git/head from a repo, it's treated as a bare directory. For whatever reason, bare repos have special files that do things like execute code. So, using the same primitive as in the second argument injection, code execution is easy. git is scary and so is argument injection. Great blog on an undervalued bug class!
Analysis Summary
# Vulnerability: Multiple Argument Injection and File Deletion Flaws in Gogs
## CVE Details
- **CVE-2024-39930**: CVSS 9.9 (Critical) - SSH Argument Injection (RCE)
- **CVE-2024-39932**: CVSS 9.9 (Critical) - Changes Preview Argument Injection (RCE)
- **CVE-2024-39931**: CVSS 9.9 (Critical) - Internal File Deletion (RCE via Repo Corruption)
- **CVE-2024-39933**: CVSS 7.7 (High) - Tagging Argument Injection (Arbitrary File Read)
- **CWE**: CWE-88 (Improper Neutralization of Argument Delimiters), CWE-73 (External Control of File Name or Path)
## Affected Systems
- **Products**: Gogs (Open-source self-hosted Git service)
- **Versions**: Up to and including version 0.13.0 (and commit `5bdf91e`).
- **Configurations**:
- **CVE-2024-39930**: Requires built-in SSH server enabled (non-default) and valid user credentials or open self-registration.
- **General**: Attacker must have an authenticated account on the Gogs instance.
## Vulnerability Description
Gogs suffers from multiple vulnerabilities where user-supplied input is improperly sanitized before being passed as arguments to system commands (Git and env).
1. **SSH Argument Injection (CVE-2024-39930)**: When handling SSH `env` requests, Gogs fails to prevent argument injection during the concatenation of environment keys and values. An attacker can use flags like `--split-string` (in specific `env` binary versions) to execute arbitrary commands.
2. **Changes Preview Injection (CVE-2024-39932)**: An injection via `git diff` using the `--output` flag allows an attacker to truncate files. By corrupting `.git/HEAD`, the repository is treated as a bare repo, allowing the execution of malicious `core.fsmonitor` configurations.
3. **Tagging Injection (CVE-2024-39933)**: An injection in `git tag` via the `--file` flag allows an attacker to read arbitrary files by setting the tag message to the contents of a local file.
4. **Internal File Deletion (CVE-2024-39931)**: A flaw allowing the deletion of internal repository files (like `.git/HEAD`), leading to RCE via the same mechanism as CVE-2024-39932.
## Exploitation
- **Status**: PoC demonstrated by researchers; no confirmed "in the wild" exploitation reported yet, but ~7300 instances are publicly visible.
- **Complexity**: High (Requires specific environment conditions, e.g., GLIBC-based `env` for CVE-2024-39930).
- **Attack Vector**: Network (Authenticated).
## Impact
- **Confidentiality**: High (Full access to all source code and system files).
- **Integrity**: High (Ability to modify source code, plant backdoors, or delete data).
- **Availability**: High (Ability to wipe all hosted repositories).
## Remediation
### Patches
As of the disclosure date, the maintainers have **not released official patches**. The researchers suggest manually applying the patches provided by SonarSource:
- [hXXps://github[.]com/SonarSource/vulnerability-research/tree/main/patches/gogs]
### Workarounds
- **Disable Built-in SSH**: Use the system's native SSH server instead of the Gogs built-in Go implementation.
- **Disable Self-Registration**: Prevent unknown actors from obtaining the required authentication.
- **Restrict Access**: Place Gogs instances behind a VPN or IP allowlist.
## Detection
- **Log Monitoring**: Scan SSH logs for suspicious `env` requests containing flags (e.g., strings starting with `--`).
- **Network Traffic**: Look for HTTP requests with the path pattern `///_preview//--` which targets the `git diff` injection.
- **File Integrity**: Monitor for unexpected modifications or deletions of `.git/HEAD` files within the Gogs data directory.
## References
- SonarSource Blog: [hXXps://www[.]sonarsource[.]com/blog/securing-developer-tools-unpatched-code-vulnerabilities-in-gogs-1-2/]
- GitHub Repository: [hXXps://github[.]com/gogs/gogs]
- Argument Injection Vectors: [hXXps://sonarsource[.]github[.]io/argument-injection-vectors-dataset/]