Skip to content

Security: stop Exec[bucket-create-*] leaking the couchbase password in plaintext#57

Open
kochj23 wants to merge 1 commit into
justicel:masterfrom
kochj23:fix/couchbase-bucket-password-leak
Open

Security: stop Exec[bucket-create-*] leaking the couchbase password in plaintext#57
kochj23 wants to merge 1 commit into
justicel:masterfrom
kochj23:fix/couchbase-bucket-password-leak

Conversation

@kochj23

@kochj23 kochj23 commented Jul 1, 2026

Copy link
Copy Markdown

Summary

Closes #42.

couchbase::bucket interpolates the cluster password (and, for couchbase-type buckets, the bucket password) directly into the command and unless strings of Exec[bucket-create-*]:

command   => "couchbase-cli bucket-create -c 127.0.0.1 -u ${user} -p '${password}' ...",
unless    => "couchbase-cli bucket-list -c 127.0.0.1 -u ${user} -p '${password}' | grep -x ${bucketname}",
logoutput => true,

Puppet logs the literal command attribute whenever an Exec fails (change from notrun ... failed: <command> returned 1), and if the node uses tagmail that failure report is e-mailed out. As reported in #42, this exposes the couchbase password in plaintext on every failed run. Note this happens regardless of logoutput, because the leak is the command line itself, not the command's stdout/stderr.

Fix

Export the passwords through the Exec's environment (CB_PASSWORD / CB_BUCKET_PASSWORD) and reference them as shell variables in the command, so the secret never appears in any string Puppet logs:

environment => ["CB_PASSWORD=${password}", ...],
command     => "... -p \"\$CB_PASSWORD\" ...",
provider    => shell,      # needed so the shell expands $CB_PASSWORD
logoutput   => on_failure,

The bucket password is only exported when one is actually configured.

Security impact

Eliminates plaintext disclosure of the couchbase cluster/bucket passwords in Puppet run reports and tagmail e-mails. Environment variables are not printed in Puppet's failure messages, so the credential stays out of logs.

Tests

Adds spec/defines/bucket_spec.rb. Categories covered:

  • Unit — resource is created with provider => shell, logoutput => on_failure.
  • Integration — ordering/anchoring against Class[couchbase::config].
  • Functional — memcached bucket path (only CB_PASSWORD exported, no --bucket-password).
  • Security — asserts the cluster/bucket passwords are absent from command and unless, are referenced via $CB_PASSWORD/$CB_BUCKET_PASSWORD, and are carried only in environment.
  • Edge case — password containing shell metacharacters stays out of the command.
  • Regression — reproduces the Failure of ::couchbase::bucket/Exec[bucket-create-*] Logs Passwords in Plain Text #42 leak condition and proves it is closed.
  • Retry — N/A (idempotent Exec guarded by unless); placeholder kept for parity.

Locally bundle exec rspec spec/defines/bucket_spec.rb is green: 285 examples, 0 failures (Puppet 4.10, stdlib 4.25.1, across all supported OSes).

🤖 Generated with Claude Code

Closes justicel#42.

couchbase::bucket interpolated the cluster and bucket passwords directly
into the Exec's `command` and `unless` strings. Puppet logs the literal
command attribute whenever an Exec fails ("change from notrun ... failed:
<command> returned 1"), and tagmail e-mails that failure report, so the
password was exposed in plaintext on every failed run -- regardless of the
logoutput setting (the leak is the command line, not the command output).

Fix: export the passwords through the Exec environment (CB_PASSWORD /
CB_BUCKET_PASSWORD) and reference them as shell variables in the command,
so the secret never appears in any string Puppet logs. The Exec now uses
`provider => shell` (needed for variable expansion) and `logoutput =>
on_failure`.

Adds spec/defines/bucket_spec.rb asserting the passwords never appear in
the command/unless strings and are only carried in the environment.

Test categories covered: Unit, Integration, Functional, Security,
Edge-case, Regression, and a Retry placeholder (N/A -- idempotent Exec).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Failure of ::couchbase::bucket/Exec[bucket-create-*] Logs Passwords in Plain Text

1 participant