Skip to content

Commit

Permalink
rpk bundle: Fix race condition in SASL credential redaction
Browse files Browse the repository at this point in the history
This commit addresses a bug where SASL credentials
stored only in the redpanda.yaml could be redacted
before being used for authentication.

If the credentials were not provided elsewhere
(e.g. via environment variables or flags), the
redacted value would be used, leading to
authentication errors due to invalid credentials.
  • Loading branch information
r-vasquez committed Jan 2, 2025
1 parent f28f9fa commit 57dc975
Showing 1 changed file with 38 additions and 21 deletions.
59 changes: 38 additions & 21 deletions src/go/rpk/pkg/cli/debug/bundle/bundle_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,38 +470,42 @@ func saveDataDirStructure(ps *stepParams, y *config.RedpandaYaml) step {
// Writes the config file to the bundle, redacting SASL credentials.
func saveConfig(ps *stepParams, y *config.RedpandaYaml) step {
return func() error {
yCp, err := createRedpandaConfigCopy(y)
if err != nil {
return err
}
// Redact SASL credentials
redacted := "(REDACTED)"
if y.Rpk.KafkaAPI.SASL != nil {
y.Rpk.KafkaAPI.SASL.User = redacted
y.Rpk.KafkaAPI.SASL.Password = redacted
if yCp.Rpk.KafkaAPI.SASL != nil {
yCp.Rpk.KafkaAPI.SASL.User = redacted
yCp.Rpk.KafkaAPI.SASL.Password = redacted
}
// We want to redact any blindly decoded parameters.
redactOtherMap(y.Other)
redactOtherMap(y.Redpanda.Other)
redactServerTLSSlice(y.Redpanda.KafkaAPITLS)
redactServerTLSSlice(y.Redpanda.AdminAPITLS)
if y.SchemaRegistry != nil {
for _, server := range y.SchemaRegistry.SchemaRegistryAPITLS {
redactOtherMap(yCp.Other)
redactOtherMap(yCp.Redpanda.Other)
redactServerTLSSlice(yCp.Redpanda.KafkaAPITLS)
redactServerTLSSlice(yCp.Redpanda.AdminAPITLS)
if yCp.SchemaRegistry != nil {
for _, server := range yCp.SchemaRegistry.SchemaRegistryAPITLS {
redactOtherMap(server.Other)
}
}
if y.Pandaproxy != nil {
redactOtherMap(y.Pandaproxy.Other)
redactServerTLSSlice(y.Pandaproxy.PandaproxyAPITLS)
if yCp.Pandaproxy != nil {
redactOtherMap(yCp.Pandaproxy.Other)
redactServerTLSSlice(yCp.Pandaproxy.PandaproxyAPITLS)
}
if y.PandaproxyClient != nil {
redactOtherMap(y.PandaproxyClient.Other)
y.PandaproxyClient.SCRAMPassword = &redacted
y.PandaproxyClient.SCRAMUsername = &redacted
if yCp.PandaproxyClient != nil {
redactOtherMap(yCp.PandaproxyClient.Other)
yCp.PandaproxyClient.SCRAMPassword = &redacted
yCp.PandaproxyClient.SCRAMUsername = &redacted
}
if y.SchemaRegistryClient != nil {
redactOtherMap(y.SchemaRegistryClient.Other)
y.SchemaRegistryClient.SCRAMPassword = &redacted
y.SchemaRegistryClient.SCRAMUsername = &redacted
if yCp.SchemaRegistryClient != nil {
redactOtherMap(yCp.SchemaRegistryClient.Other)
yCp.SchemaRegistryClient.SCRAMPassword = &redacted
yCp.SchemaRegistryClient.SCRAMUsername = &redacted
}

bs, err := yaml.Marshal(y)
bs, err := yaml.Marshal(yCp)
if err != nil {
return fmt.Errorf("couldn't encode the redpanda config as YAML: %w", err)
}
Expand All @@ -521,6 +525,19 @@ func redactOtherMap(other map[string]interface{}) {
}
}

func createRedpandaConfigCopy(y *config.RedpandaYaml) (*config.RedpandaYaml, error) {
bs, err := yaml.Marshal(y)
if err != nil {
return nil, fmt.Errorf("unable to serialize the loaded redpanda config as YAML: %v", err)
}
var cp config.RedpandaYaml
err = yaml.Unmarshal(bs, &cp)
if err != nil {
return nil, fmt.Errorf("unable to decode the redpanda config: %v", err)
}
return &cp, nil
}

// Saves the contents of '/proc/cpuinfo'.
func saveCPUInfo(ps *stepParams) step {
return func() error {
Expand Down

0 comments on commit 57dc975

Please sign in to comment.