URL Secrets Exposure in Logs
Summary
The redpanda-connect binary provides a command named echo to parse a config file and echo back its normalized version.
The normalization phase encompasses redacting secrets which may be present in the configuration.
When the configuration for a NATS connector gets processed by the echo command the redpanda-connect utility fails at redacting passwords which may be present inside URLs.
In some deployments this may expose the secrets to actors that are not authorized to access the YAML config file but have access to logs where the output of the program is collected.
Verified on Redpanda Connect at commit https://github.com/redpanda-data/connect/commit/6b917811adfe0ebdf3b9323c7a80625f6cf2154d.
Details
The following snippet from connect/internal/impl/nats/connection.go shows the definition of urls field using NewStringListField() and two examples of valid values:
func connectionHeadFields() []*service.ConfigField {
return []*service.ConfigField{
service.NewStringListField("urls").
Description("A list of URLs to connect to. If an item of the list contains commas it will be expanded into multiple URLs.").
Example([]string{"nats://127.0.0.1:4222"}).
Example([]string{"nats://username:[email protected]:4222"}),
service.NewIntField("max_reconnects").
Description("The maximum number of times to attempt to reconnect to the server. If negative, it will never stop trying to reconnect.").
Optional().
Advanced(),
}
}The second example shows a URL containing a username and password pair, which is exactly the problematic case since the field declared using NewStringListField() will not be redacted.
PoC
- Clone the repository and build the project:
git clone https://github.com/redpanda-data/connect
cd connect
task build:redpanda-connect - Create the test YAML config file:
cat > config.yaml <<'EOF'
input:
nats:
urls:
- nats://127.0.0.1:4222
- nats://[email protected]:4222
- nats://demo_user:[email protected]:4222
subject: test.subject
auth:
user: separate_user
password: separate_password
output:
drop: {}
EOF- Run the following command:
target/redpanda-connect echo config.yaml- Notice that while the
input.nats.auth.passwordfield is redacted, the element ofinput.nats.urlswhich contains a password is not.
Suggested Remediation
Use the NewURLListField() function to create urls field to benefit from its support for redaction:
diff --git a/internal/impl/nats/connection.go b/internal/impl/nats/connection.go
index 3803e58..1e3346a 100644
--- a/internal/impl/nats/connection.go
+++ b/internal/impl/nats/connection.go
@@ -29,7 +29,7 @@ import (
// docs.
func connectionHeadFields() []*service.ConfigField {
return []*service.ConfigField{
- service.NewStringListField("urls").
+ service.NewURLListField("urls").
Description("A list of URLs to connect to. If an item of the list contains commas it will be expanded into multiple URLs.").
Example([]string{"nats://127.0.0.1:4222"}).
Example([]string{"nats://username:[email protected]:4222"}),
Credits
Found by Team Atlanta. Collected and verified by OSTIF using AI with their own harness. Manually verified, fixed, and reported by Shielder.
Source: redpanda-data/connect