Blog post Securing Developer Tools: Unpatched Code Vulnerabilities in Gogs (1/2) Thomas Chauchefoin, Paul Gerste Vulnerability Researchers July 2, 2024 Date Vulnerability research Code security Most companies today value their source code as an important asset and rely on cloud services like GitHub or operate their own source code hosting platform to manage this asset. One option for this is Gogs , an open-source solution for self-hosting source code. With over 44,000 stars on GitHub, Gogs is among the most popular Go projects. Its Docker image has been downloaded over 90 million times, indicating that many developers use it. In light of our blog post series on securing developer tools, we investigated the code base of Gogs for security vulnerabilities. We discovered four unfixed vulnerabilities in Gogs that allow attackers to compromise vulnerable instances, enabling them to steal source code, plant code backdoors, wipe all code, and more. This blog post will first cover the impact of the vulnerabilities we found and reported. We will then discuss the technical details of one of those vulnerabilities. Finally, we will provide recommendations and patches for users to help them protect their Gogs installations. This blog post is the first in a series of two. Next week's article will cover more details on the remaining vulnerabilities. Impact We found the following vulnerabilities and reported them to the maintainers of Gogs: Argument Injection in the built-in SSH server (CVE-2024-39930, CVSS 9.9 Critical) Argument Injection when tagging new releases (CVE-2024-39933, CVSS 7.7 High) Argument Injection during changes preview (CVE-2024-39932, CVSS 9.9 Critical) Deletion of internal files (CVE-2024-39931, CVSS 9.9 Critical) Unfortunately, the maintainers did not implement fixes and stopped communicating with us at some point after initially accepting our report. All four vulnerabilities are still present in the latest release of Gogs (0.13.0) and the latest commit in the Gogs repository ( 5bdf91e at the time of writing). To protect yourself, read our recommendation section below. Attackers can use vulnerabilities 1, 3, and 4 to execute arbitrary commands on the Gogs server. The commands will run under the same use that Gogs is running as (configured via RUN_USER ). This allows them to read all source code on the instance, modify any code, delete all code, or attack internal hosts reachable from the Gogs server. Vulnerability 2 allows attackers to read arbitrary files from the Gogs server. These files include the source code stored on the Gogs instance and configuration secrets, likely allowing the attacker to impersonate other users and gain more privileges. All four vulnerabilities require an attacker to be authenticated. You can find more details about the exploitability of vulnerability 1 in the Exploit Requirements section below. A quick Shodan search lists around 7300 open Gogs instances: We did not confirm how many of these are exploitable, nor do we have any data on whether or not malicious actors are exploiting these vulnerabilities in the wild. Technical Details of CVE-2024-39930 Like many source code hosting platforms, Gogs allows users to push and pull Git repositories over SSH. For this, Gogs comes with a built-in SSH server that admins can activate. This built-in server uses the golang.org/x/crypto/ssh package under the hood, which does most of the heavy lifting, such as implementing the SSH protocol, handling authentication, etc. Gogs adds code on top of that, which handles authorization and maps repos to their respective internal file path. This is done by executing a helper executable that is part of Gogs. To understand the vulnerability we found in the binding code between the SSH library and the helper executable, we will take a quick detour into the SSH protocol: An SSH connection starts with a client establishing a TCP connection with the server (1). The client and server then perform a handshake (2) that includes authentication, usually using public key cryptography. After the handshake successfully finishes, the client opens a channel with the type session (3), and the server confirms (4). Inside this channel, the client can send requests consisting of a type and a payload. For example, a client would send a shell request (5) to establish a classic interactive SSH session. For Git-over-SSH, the client uses env and exec requests. While the former is used to set environment variables like GIT_PROTOCOL , the latter is used to start a Git process on the server that the client can then directly talk to and exchange repository data. Gogs handles these requests in internal/ssh/ssh.go : switch req.Type { case "env": var env struct { Name string Value string } if err := ssh.Unmarshal(req.Payload, &env); err != nil { log.Warn("SSH: Invalid env payload %q: %v", req.Payload, err) continue } // Sometimes the client could send malformed command (i.e. missing "="), // see https://discuss.gogs.io/t/ssh/3106
SonarSource researchers identified four unpatched vulnerabilities in the Gogs self-hosted Git service, including