Malformed credential-bearing Redis URL is echoed verbatim into startup error output, leaking user:password (CWE-532/CWE-209)
low Fully Valid high confidence
Status
Fully Valid
Full chain traced through the go-redis and net/url source on disk: url.Parse failures embed the raw credentialed URL with no redaction, and filebrowser surfaces it at startup. Fully_valid, low.
Repository / Component
Plain-English Description
If the Redis connection string used for upload caching is misspelled in a way that makes it fail basic URL parsing, the server prints the whole string — including the username and password — into its startup output and logs.
Description of the Underlying Issue
newRedisUploadCache (http/upload_cache_redis.go:23-26) calls redis.ParseURL and, on failure, wraps the returned error verbatim with fmt.Errorf("invalid redis URL: %w", err). When the failure occurs at the underlying net/url.Parse stage (for example an invalid port, a control character, or a bad percent-escape), go-redis returns url.Parse's error unchanged (go-redis options.go:497-499), and Go's *url.Error.Error() formats the raw input URL with %q and performs no userinfo redaction (net/url url.go:34,483,489). The wrapped error is forwarded unchanged by the memory-cache constructor (http/upload_cache_memory.go:82) and re-wrapped at cmd/root.go:184 as "failed to initialize upload cache: %w", then surfaced to cobra at startup. The net effect is that a credential-bearing redis:// URL that is malformed at the parse layer has its full user:password@host component written to startup output/logs.
Potential Attack
This is primarily an operator-facing information-exposure defect rather than an actively attacker-driven one. An operator who configures a Redis cache URL containing credentials but mistypes it in a way that fails url.Parse (e.g. redis://user:s3cret@host:99abc/0) causes the plaintext credential to be emitted to console output, log files, container logs, or a process supervisor's captured output. Any party who can read those logs — a co-located low-privilege OS user, a log-aggregation pipeline, a CI/build log, or an attacker who has gained read access to logs — then recovers the Redis credentials.
Outcomes of Potential Attack
Disclosure of the Redis connection credentials to anyone able to read the server's startup output or logs. With those credentials an attacker who can reach the Redis instance can read or tamper with cached upload state and, depending on how that Redis is shared, pivot to other data stored in it. The exposure is confined to the credentials present in the misconfigured URL.
Affected Scope
newRedisUploadCache (http/upload_cache_redis.go:23-26) -> cmd/root.go:182-185 -> cobra startup output
Suggested Fix (plain english)
When the Redis URL fails to parse, log only a generic message or the parse reason — never the raw URL — and strip the username/password before recording anything.
Suggested Fix (detailed)
In newRedisUploadCache (http/upload_cache_redis.go:23-26), do not wrap the raw ParseURL error with %w when reporting it upward. Instead log/return a static message (e.g. "invalid redis URL: could not parse") or, if a reason is needed, re-parse defensively and emit only url.URL.Redacted() (which masks userinfo) rather than the original string. Apply the same redaction at any log site that could receive the wrapped error (cmd/root.go:184). Verify by configuring a credential-bearing URL that is malformed at the parse layer (e.g. redis://user:s3cret@host:99abc/0) and confirming the startup output contains no username or password. On ParseURL failure, log a static message or only the parse reason; never wrap %w of the raw error, or redact userinfo (url.URL.Redacted) before logging.
Validation
Full chain traced through the go-redis and net/url source on disk: url.Parse failures embed the raw credentialed URL with no redaction, and filebrowser surfaces it at startup. Fully_valid, low.
Full Evidence
http/upload_cache_redis.go:23-26 redis.ParseURL error wrapped verbatim as 'invalid redis URL: %w'
dependency go-redis v9.19.0 options.go:497-499 ParseURL returns url.Parse's error directly on parse failure (its own scheme/path/db errors at :508/:529/:532 do NOT embed the URL)
Go stdlib net/url url.go:483/489 return &Error{'parse', rawURL, err} and url.go:34 (e *Error).Error() formats '%q' of the raw URL with NO userinfo redactionhttp/upload_cache_memory.go:82 forwards the error unchanged; cmd/root.go:184 wraps as 'failed to initialize upload cache: %w' and returns it to cobra
Proven fact: When a credential-bearing redis URL fails at the url.Parse stage (invalid port, control character, or bad percent-escape), the resulting error string contains the full user:password@ URL and is printed to startup output/logs (CWE-532/CWE-209)
Unvalidated fact: Trigger requires the operator to configure a URL malformed specifically at the url.Parse layer; a well-formed credential URL parses cleanly and does not leak
Unvalidated fact: Log readership breadth (who can read startup output) is deployment-dependent
http/upload_cache_redis.go:23-26 — redis.ParseURL error wrapped verbatim as 'invalid redis URL: %w' (confirmed on disk: line 25 `return nil, fmt.Errorf("invalid redis URL: %w", err)`)dependency go-redis v9.19.0 options.go:497-499 — ParseURL returns url.Parse's error directly on parse failure; its own scheme/path/db errors (options.go:508/529/532) do not embed the URL
Go stdlib net/url url.go:483/489 return &Error{'parse', rawURL, err}; url.go:34 (e *Error).Error() formats '%q' of the raw URL with NO userinfo redactionProven fact: When a credential-bearing redis URL fails at the url.Parse stage (invalid port, control character, or bad percent-escape), the resulting error string contains the full user:password@ URL and is printed to startup output/logs (CWE-532/CWE-209).
Proven fact: go-redis returns url.Parse's error unmodified for parse-stage failures, and net/url's Error type renders the raw URL without redaction, so no layer between ParseURL and cobra strips the credentials.
Unvalidated fact: Trigger requires the operator to configure a URL malformed specifically at the url.Parse layer; a well-formed credential URL parses cleanly and does not leak.
Unvalidated fact: Log readership breadth (who can read startup output) is deployment-dependent.
cmd/root.go:182-185 error propagated as 'failed to initialize upload cache: %w' and returned to cobra (printed at startup)
go-redis ParseURL delegates to url.Parse, whose *url.Error message embeds the full input URL including embedded user:pass credentials