GetDLQ returns connector Settings unredacted — potential secret exposure via API
- Dominant language
- Go
- Stars
- 610
- Forks
- 63
- Avg merge
- 12h 28m
- Merged PRs (30d)
- 57
Description
## Summary
The `GetDLQ` API response returns the DLQ connector's `Settings` map **unredacted**. Connector settings routinely carry secrets (database DSNs with embedded passwords, SASL credentials, access keys, API tokens), so this can leak secrets to any caller of the HTTP/gRPC API — and to any UI built on `GetDLQ`.
## Evidence
`pkg/http/api/toproto/pipeline.go:82-91` copies `in.Settings` straight into the proto response with no masking:
```go
func PipelineDLQ(in pipeline.DLQ) *apiv1.Pipeline_DLQ {
return &apiv1.Pipeline_DLQ{
Plugin: in.Plugin,
Settings: in.Settings, // <-- raw settings, no redaction
//nolint:gosec // no risk of overflow, existing pipeline that's already been validated
WindowSize: uint64(in.WindowSize),
//nolint:gosec // no risk of overflow, existing pipeline that's already been validated
WindowNackThreshold: uint64(in.WindowNackThreshold),
}
}
```
## Contrast with the log path
Log output already guards against exactly this. `pkg/foundation/log/redact.go` (`RedactAll` / `RedactedConfig.MarshalZerologObject`, lines 26-91) redacts every config value (leaving only keys visible) precisely because "connector settings (config.Config, a map[string]string) routinely contain secrets: database URLs with embedded passwords, SASL credentials, access keys." That redaction is applied at log call sites only — it is **not** applied to the `GetDLQ` RPC response, so the wire path leaks what the log path is careful to mask.
## Impact
Any secret embedded in a pipeline's DLQ-destination settings (e.g. a Postgres DSN with a password, a Kafka SASL password) is returned in plaintext to any client that can call `GetDLQ` over HTTP or gRPC. The exposure becomes more visible once a UI renders the DLQ config panel in a browser (the v0.18 UI epic builds a DLQ view on top of this RPC). Conduit's API is unauthenticated by default, which widens the blast radius.
## Suggested disposition
Likely **Tier-1 / security**. Fix should redact settings values on the API response path (mirroring `redact.go`'s behavior — mask values, keep keys), and ship with a **regression test** asserting `GetDLQ` never returns raw secret-bearing values. Related upstream work on per-parameter sensitivity metadata is tracked in #2566; a fix here should not block on that (the interim redact-all-values approach used by `RedactAll` is available now).
## Notes
Discovered during research for the v0.18 P6 DLQ record-visibility design doc (`docs/design-documents/20260715-dlq-record-visibility.md`), where this gap is documented as a failure mode. Filing separately so it gets a tracked fix + regression test rather than living only in a design doc.
🤖 Generated with Claude Code
Contributor guide
Research direction
Start in pkg/http/api/toproto/pipeline.go at PipelineDLQ and compare the existing masking behavior in pkg/foundation/log/redact.go, especially RedactAll. Add a regression test for the GetDLQ response that verifies settings keys remain available while secret-bearing values are not returned verbatim. Done means the API response no longer exposes raw settings values.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100