Skip to content

fix(cluster): redact the Builder password behind cassandra.expose_credentials - #144

Merged
CodeLieutenant merged 2 commits into
trunkfrom
claude/vigorous-shaw-4a6969
Aug 8, 2026
Merged

fix(cluster): redact the Builder password behind cassandra.expose_credentials#144
CodeLieutenant merged 2 commits into
trunkfrom
claude/vigorous-shaw-4a6969

Conversation

@CodeLieutenant

@CodeLieutenant CodeLieutenant commented Aug 5, 2026

Copy link
Copy Markdown
Member

Problem

php_scylladb_cluster_builder_properties copied the stored password into the object properties table in clear text (src/Cluster/BuilderHandlers.c). Every operation that reads object properties printed it:

  • var_dump($builder)
  • print_r($builder)
  • get_object_vars($builder)
  • (array) $builder
  • the debug panel or exception renderer of any framework that dumps objects

This defeated the #[\SensitiveParameter] attribute on Cassandra\Cluster\Builder::withCredentials(). That attribute only redacts the value in stack traces.

Fix

The properties table now holds "***" instead of the credential. The password key stays present and the null-when-unset branch does not change, so the shape of a dump is the same as before.

The real value is still reachable for debugging, behind a new INI setting:

cassandra.expose_credentials = On

Off by default, so redaction is the safe default. Turn it on to put the real password back in the properties table.

The setting is PHP_INI_SYSTEM. A request cannot call ini_set() to turn the redaction off, so a library, a template, or a debug handler cannot unredact the value. Only the operator can, through php.ini or php -d cassandra.expose_credentials=1.

Scope

  • src/SSLOptions/ registers no get_properties handler at all, so the private key passphrase never reached a properties table. No change was needed there.
  • No test asserted on the password property. tests/Support/helpers.php only calls withCredentials(), it never reads the value back.
  • The Cluster builder was the only get_properties in the tree that touched a secret.

Tests

New file tests/Unit/ClusterBuilderCredentialsTest.php with 6 cases:

  1. (array) $builder keeps the password key and returns "***".
  2. print_r() and var_export() do not contain the credential.
  3. username and password are both null when no credentials are set.
  4. cassandra.expose_credentials defaults to off.
  5. ini_set() on the setting returns false and the value stays redacted.
  6. A child process started with -d cassandra.expose_credentials=1 prints the real password, and the same child without the flag prints ***.

Case 6 needs a fresh process, because a PHP_INI_SYSTEM setting cannot change inside a request. The helper reads SCYLLADB_EXTENSION_PATH to find the module to load, and marks the test skipped if the child cannot load it. Both paths were checked:

SCYLLADB_EXTENSION_PATH=$PWD/out/DebugPHP8.5NTS/cassandra.dylib \
  php -n -d extension=$PWD/out/DebugPHP8.5NTS/cassandra.dylib ./vendor/bin/pest --testsuite=Unit

With the variable set: 6 passed. Without it: 5 passed, 1 skipped.

Full Unit suite: 809 passed, 1 failed. The failure is the pre-existing UuidTest case at tests/Unit/Uuid/UuidTest.php:112. It spawns a child with -d extension=cassandra, which resolves through extension_dir and therefore loads an installed build instead of the build under test. It is unrelated to this change.

Also changed

cassandra.ini documents the new setting.

php_scylladb_cluster_builder_properties copied the stored password into
the object properties table in clear text. Every operation that reads
object properties printed it: var_dump(), print_r(), get_object_vars(),
(array) casts, and the debug renderer of any framework or exception
handler.

This defeated the #[\SensitiveParameter] attribute on
Cassandra\Cluster\Builder::withCredentials(), which only redacts the
value in stack traces.

Put the fixed string "***" in the table instead. The key stays present,
and the null-when-unset branch does not change, so the shape of a dump
is the same as before.

src/SSLOptions/ registers no get_properties handler, so the private key
passphrase was never exposed. No change is needed there.
@mergify

mergify Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

The previous commit always replaced the password in the Builder
properties table with "***". That also removed a value that is useful
when you debug a connection problem.

Add the cassandra.expose_credentials INI setting. It is off by default,
so the redaction stays the safe default. Turn it on to put the real
password back in the properties table.

The setting is PHP_INI_SYSTEM. A request cannot call ini_set() to turn
the redaction off, so a library or a debug handler cannot unredact the
value. Only the operator can, through php.ini or the -d option.
@CodeLieutenant CodeLieutenant changed the title fix(cluster): redact the password in Builder object properties fix(cluster): redact the Builder password behind cassandra.expose_credentials Aug 5, 2026
@CodeLieutenant
CodeLieutenant merged commit 74eabd9 into trunk Aug 8, 2026
29 checks passed
@CodeLieutenant
CodeLieutenant deleted the claude/vigorous-shaw-4a6969 branch August 8, 2026 09:39
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.

1 participant