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 6b91781.
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:password@127.0.0.1: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://demo_user@127.0.0.1:4222
- nats://demo_user:RedpandaNatsUrlSecret42@127.0.0.1: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.password field is redacted, the element of input.nats.urls which 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:password@127.0.0.1:4222"}),
Credits
Found by Team Atlanta.
Collected and verified by OSTIF using AI with their own harness.
Manually verified, fixed, and reported by Shielder.
Summary
The
redpanda-connectbinary provides a command namedechoto 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
echocommand theredpanda-connectutility 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 Connectat commit 6b91781.Details
The following snippet from
connect/internal/impl/nats/connection.goshows the definition ofurlsfield usingNewStringListField()and two examples of valid values: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
input.nats.auth.passwordfield is redacted, the element ofinput.nats.urlswhich contains a password is not.Suggested Remediation
Use the
NewURLListField()function to createurlsfield to benefit from its support for redaction:Credits
Found by Team Atlanta.
Collected and verified by OSTIF using AI with their own harness.
Manually verified, fixed, and reported by Shielder.