Repository navigation
Match the user name as a whole token in host_receipts.sanitize() - #227
Merged
seathatflowsinourveins merged 2 commits intoSep 25, 2026
Merged
Conversation
sanitize() replaced $USER as a substring, so a short account name was cut
out of ordinary words. A two-letter name inside "recorded-host-20260101"
made hardware_profile.py --record-host refuse that id ("contains the local
user name"), and captured excerpts lost letters from words ("cached"
became "cach<user>" for user "ed"). The name is now replaced only where no
letter, digit or underscore touches it. An escape that ends in a letter or
digit just before it (JSON \n, \r, \t, /, a \x2f or a URL's %2F)
still counts as a separator, so encoded home paths stay redacted; the
$HOME replacement and the PRIVATE_CONTENT patterns are unchanged.
The tests simulate a two-letter account name on every host; CI runs as
"runner" and never hit this. The existing refusal test used "ramstation"
for user "ram", which is the substring assumption itself; it now uses the
name as a token ("ram-station") and adds two-letter cases.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
# Conflicts: # manifests/evidence.json
seathatflowsinourveins
enabled auto-merge (squash)
September 25, 2026 13:55
seathatflowsinourveins
deleted the
claude/user-name-token-sanitize-20260924
branch
September 25, 2026 14:09
This was referenced Sep 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
host_receipts.sanitize()replaced$USERas a substring. A short account name is often part of ordinary words, so under an account nameded(insiderecorded),hardware_profile.py --record-host recorded-host-20260101refused the id ("contains the local user name or a home path"), andhost_receipts.py recordexcerpts lost letters (cachedbecamecach<user>). CI runs asrunnerand never hit this. On unmodified main it breakstests.test_new_host_grand_list.RecordHostToGrandListTests.test_recorded_host_gets_non_null_measured_in_the_grand_liston any host whose account name occurs inside that id.Change.
sanitize()now replaces the name only as a whole token (user_name_pattern()): no letter, digit or underscore may touch it on either side. An escape that ends in a letter or digit just before it (JSON\n,\r,\t,\u002f, a\x2for a URL's%2F) still counts as a separator, so encoded home paths stay redacted. The$HOMEto~replacement and thePRIVATE_CONTENTpatterns are unchanged. Another account whose name merely starts with this one (/home/ed_old/...) is still redacted, by the personal-home-path pattern.Trade-off. A name glued to a letter, digit or underscore (
edmbp,ed2,ed_old) is no longer redacted or refused on its own. A name set off by-,.,/,\,@, quotes or whitespace still is, soed-mbp-20260101is still refused.Tests simulate the
edaccount on every host:SanitizeUserNameTests: words that contain the name are kept, the name as a token is redacted, home paths stay redacted in eight forms (literal$HOME, Linux and Windows layouts, a Claude project slug, URL-encoded,\u002fand\x2fescapes, another account's home), as does the name after a JSON\n, and arecordround trip keepscachedin the excerpt.RecordHostTests:recorded-host-20260101is accepted with its label and evidence path intact;ed-mbp-…andmbp-ed-…are refused. The existing refusal test usedramstationfor userram, which is the substring rule itself; it now usesram-station.RecordHostToGrandListTests: the grand-list round trip, rerun under that account.Against the old
sanitize(), 8 of these checks fail, including when the process itself runs asrunner. All pass with the fix. Home paths in the test source are spelled through variables so thatscripts/validate.py's own publication scan passes. Thesanitize_values()docstring anddocs/contributing-evidence.mdnow describe the whole-token rule, andmanifests/evidence.jsonre-registers the three hash-listed files.Checks (macOS 26.5.1 arm64, Python 3.13.15, on 5112084, rebased onto d478fd5):
validate.ymlstep, run locally with the CI-pinned zizmor 1.30.1, actionlint 1.7.12 and gitleaks 8.30.1: all 25 steps exit 0.validate.pypassed (5338 hashed files, 145 receipts),verdict_review_gate.pyreports no verdict rows changed, and gitleaks found no leaks in 508 commits or the tree. The promotion-gate venv provisioning was not run locally.python3 -m unittest: base 4289143 ran 4713 tests,failures=2, errors=1, skipped=647. This branch ran 4719 tests,failures=1, errors=1, skipped=647. The differences are the grand-list test above, which now passes, and the 6 new tests.Two failures remain locally in
tests.test_adoption_bootstrap_macoson both base and branch. Both are environment-specific, unrelated to the user name, and not changed here:LlamaWrapperQuotingTests.test_install_path_with_shell_syntax_is_data_in_the_wrapper: its fakellama-serveris a#!/bin/shscript. With SIP enabled, dyld purgesDYLD_*when it launches the protected/bin/sh, so the script never sees theDYLD_LIBRARY_PATHthat the generated wrapper exports. The same export does reach an unprotected interpreter. The test passes on hosted macos-15 (validate-macos).PlatformDependencyInstallTests.test_places_the_verified_tarball_correctly_when_the_prefix_is_reached_through_a_symlink: it uses the npm-packed fixtures but, unlike its npm-dependent siblings, lacks@unittest.skipUnless(NPM, ...), so it errors when npm is not on PATH.🤖 Generated with Claude Code