Spoofing In gogs.io/gogs
Description
Gogs has an Authentication Bypass via Unvalidated Reverse Proxy Headers
Summary
When ENABLE_REVERSE_PROXY_AUTHENTICATION is enabled, Gogs accepts the configured authentication header (default: X-WEBAUTH-USER) directly from client requests without validating that the request originated from a trusted reverse proxy. Any remote attacker who can reach the Gogs service can forge this header to impersonate any user or trigger automatic account creation, completely bypassing authentication.
Root Cause
The vulnerability exists because Gogs reads the authentication header directly from the incoming HTTP request without any verification that the header was set by a trusted reverse proxy.
Vulnerable Code Flow
In internal/context/auth.go lines 206-234:
func authenticatedUser(store AuthStore, ctx *macaron.Context, sess session.Store) (_ *database.User, isBasicAuth, isTokenAuth bool) { // ... existing auth checks ... if uid <= 0 { if conf.Auth.EnableReverseProxyAuthentication { // Reads header DIRECTLY from client request - NO VALIDATION! webAuthUser := ctx.Req.Header.Get(conf.Auth.ReverseProxyAuthenticationHeader) if len(webAuthUser) > 0 {...
The code has zero validation that:
The request came through a reverse proxy
The header was set by the proxy (not the client)
Gogs is actually behind a reverse proxy
The direct access to Gogs is restricted
The vulnerability occurs when:
Gogs is publicly accessible (e.g., 0.0.0.0:3000)
ENABLE_REVERSE_PROXY_AUTHENTICATION = true
Proof of Concept
Prerequisites
Gogs instance with the following configuration in custom/conf/app.ini:
[auth] ENABLE_REVERSE_PROXY_AUTHENTICATION = true
An attacker can impersonate any user including administrators:
# Become admin instantly curl http://gogs.example.com/ -H "X-WEBAUTH-USER: <username>"
Recommended Fixes
Add validation to ensure headers come from trusted sources:
func authenticatedUser(store AuthStore, ctx *macaron.Context, sess session.Store) (_ *database.User, isBasicAuth, isTokenAuth bool) { // ... existing code ... if uid <= 0 { if conf.Auth.EnableReverseProxyAuthentication { // Validate request is from trusted proxy if !isRequestFromTrustedProxy(ctx.Req) { log.Warn("Reverse proxy auth header received from untrusted source: %s", ctx.RemoteAddr())...
Add configuration option:
[auth] ENABLE_REVERSE_PROXY_AUTHENTICATION = false REVERSE_PROXY_AUTHENTICATION_HEADER = X-WEBAUTH-USER ; Comma-separated list of trusted proxy IPs (default: 127.0.0.1) TRUSTED_PROXY_IPS = 127.0.0.1,::1 ; Whether to require trusted proxy validation (recommended: true) REQUIRE_TRUSTED_PROXY = true
References
Mitigation
Update Impact
Minimal update. May introduce new vulnerabilities or breaking changes.
Ecosystem | Package | Affected version | Patched versions |
|---|---|---|---|
go | 0.14.3 |
Aliases
References