Skip to content

Redact tokens, passwords and device codes from credential ToString [patch] - #202

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/169-redact-secrets
Oct 9, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/169-redact-secrets

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #169

What changed

HostingCredential and GitHubDeviceCode are records, and the compiler-generated ToString() printed every property. Logging a credential, interpolating it into a string, or putting it in an exception message therefore wrote a live GitHub or Azure DevOps token in plain text.

  • HostingCredential.ToString(): prints Token and Password as *** when they are set and blank when they aren't, the same way a record prints a null member. Kind and Username are still shown.
  • GitHubDeviceCode.ToString(): redacts DeviceCode, which is the value the token poll exchanges for a credential. UserCode, VerificationUri, ExpiresIn and Interval are still shown.
  • Redacted.Of: a new internal helper that holds the placeholder, so both types print it the same way.

Both types override ToString instead of PrintMembers. The repo's analyzers report a private PrintMembers on a sealed record as unused (IDE0051, as an error), even though the compiler calls it. The output format still matches the compiler's Name { A = …, B = … } shape.

Equality, with and the properties themselves are unchanged. The [DebuggerDisplay] the issue lists as optional isn't added: the debugger's summary line already uses the overridden ToString.

Tests (CredentialRedactionTests)

Five new tests cover a token credential, a bearer credential, a username/password credential, string interpolation and a device code. Each one asserts that the secret doesn't appear in the output and that the diagnostic fields do. With the two overrides reverted, all 5 fail. With them, the full suite passes (779/779).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rt1SUkG3bsTZEWbmGirSx3


Generated by Claude Code

…atch]

HostingCredential and GitHubDeviceCode are records, and the compiler-generated ToString printed
every property, so logging or interpolating one wrote a live GitHub or Azure DevOps token in plain
text. Both now override ToString to print Token, Password and DeviceCode as *** when present
(blank when absent), keeping Kind, Username, UserCode and VerificationUri for diagnostics.

Fixes #169

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Rt1SUkG3bsTZEWbmGirSx3
@sonarqubecloud

sonarqubecloud Bot commented Oct 9, 2026

Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor Author

In run 37870035724, Cross-Platform Tests / Test on macos-latest was cancelled at the 20-minute limit. Restore and build succeeded; the Test step was still running when it was cut off.

The diff only overrides ToString() on two records, which is unlikely to cause a hang. The same commit passed ci / .NET / Test on macos-latest in about 2 minutes, along with every other Test job. The identical Cross-Platform job on #201 also passed on macOS minutes earlier. This looks like a stuck macOS runner or test host, not this change.

I'm re-running the failed job once. If it hangs again, I'll treat it as real and investigate.


Generated by Claude Code

@matt-edmondson
matt-edmondson merged commit e26cee5 into main Oct 9, 2026
17 of 18 checks passed
@matt-edmondson
matt-edmondson deleted the fix/169-redact-secrets branch October 9, 2026 08:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants