DOKIMASecurity review report

Overview

Request path logged verbatim allows CRLF log forging and terminal-escape injection (CWE-117)

low Fully Valid high confidence

DOK-100023-FILEBROWSER-HTTP-ROUTER-MIDDLE-LOG-FORGING-VIA-UN · filebrowser · http-router-middleware

Status

Fully Valid

Log-injection path is complete in source: decoded newline in r.URL.Path reaches log.Printf unsanitized on reachable error paths. Fully_valid, low.

Repository / Component

Repository
filebrowser
Component
http-router-middleware

Plain-English Description

The server writes the requested URL straight into its log without cleaning it up. Because a URL can contain hidden newline characters, anyone sending requests can inject fake lines into the log or embed control characters that mislead whoever reads it.

Description of the Underlying Issue

In handle() the error log line at http/data.go:71 is log.Printf('%s: %v %s %v', r.URL.Path, status, clientIP, err) with no sanitization of r.URL.Path. Go's net/url percent-decodes %0A/%0D in the request target into raw CR/LF inside r.URL.Path, so a decoded newline is written verbatim into the log record. The log fires for any response with status>=400 or a non-nil err (http/data.go:69), which unauthenticated or low-privilege requests can trigger (e.g. 404/403/500). The same unsanitized pattern is mirrored at http/commands.go:34 (wsErr).

Potential Attack

An unauthenticated client sends a request whose path contains percent-encoded newlines followed by a forged log line, e.g. GET /api/resources/x%0A2026-01-01_FORGED_ENTRY, against a non-existent path so it returns 404 and reaches the error-log branch. The decoded newline splits the single log statement into an attacker-authored additional line.

Outcomes of Potential Attack

The attacker can inject fabricated log entries (framing another actor, hiding activity, corrupting audit trails) and embed terminal escape sequences that alter or spoof output in a console/tail viewing the logs (CWE-117). Impact is confined to log integrity and the trust readers place in the logs.

Affected Scope

handle() error log line (http/data.go:70-71); same pattern mirrored in http/commands.go:34 wsErr

Suggested Fix (plain english)

Clean or escape the request path before writing it to the log so newlines and control characters can't forge log lines.

Suggested Fix (detailed)

Sanitize r.URL.Path before logging at http/data.go:71 and http/commands.go:34 — wrap it with strconv.Quote (which escapes CR/LF and control characters) or strip/replace CR/LF explicitly. Verify by requesting a path containing %0A and confirming the log records a single escaped line rather than a split, attacker-controlled second line. Sanitize r.URL.Path before logging (e.g. strconv.Quote or strip CR/LF) at http/data.go:71 and http/commands.go:34.

Validation

Log-injection path is complete in source: decoded newline in r.URL.Path reaches log.Printf unsanitized on reachable error paths. Fully_valid, low.

first_opinion

Full Evidence

http/data.go:71 log.Printf('%s: %v %s %v', r.URL.Path, status, clientIP, err) with no sanitization of r.URL.Path
net/url percent-decodes %0A/%0D in the request target into raw CR/LF within r.URL.Path
http/data.go:69 the log fires on any response with status>=400 or err!=nil (e.g. 404/403/500), which unauthenticated/low-priv requests can trigger
http/commands.go:34 identical unsanitized r.URL.Path log pattern
Proven fact: r.URL.Path is percent-decoded and can contain newline characters, and it is written verbatim to the log, allowing forged log lines and terminal escape injection (CWE-117)
Unvalidated fact: Whether a downstream log aggregator re-encodes control characters (does not change the injection at the application log layer)
http/data.go:71 — log.Printf('%s: %v %s %v', r.URL.Path, status, clientIP, err) with no sanitization of r.URL.Path
http/data.go:69 — the log fires on any response with status>=400 or err!=nil (e.g. 404/403/500), which unauthenticated/low-priv requests can trigger
http/commands.go:34 — identical unsanitized r.URL.Path log pattern
Proven fact: r.URL.Path is percent-decoded and can contain newline characters, and it is written verbatim to the log, allowing forged log lines and terminal escape injection (CWE-117).
Unvalidated fact: Whether a downstream log aggregator re-encodes control characters; that does not change the injection at the application log layer.
http/data.go:70-71 clientIP := realip.FromRequest(r); log.Printf("%s: %v %s %v", r.URL.Path, status, clientIP, err) with no sanitization of r.URL.Path
r.URL.Path is percent-decoded by net/url, so %0A becomes a raw newline reaching log.Printf
Same unsanitized-path pattern is mirrored in http/commands.go:34 wsErr (command-execution component)