fix(registry_keys): truncate the value preview char-safely via jsonguard - #7
Draft
h4x0r wants to merge 2 commits into
Draft
fix(registry_keys): truncate the value preview char-safely via jsonguard#7h4x0r wants to merge 2 commits into
h4x0r wants to merge 2 commits into
Conversation
format_data_preview truncates a decoded REG_SZ/REG_EXPAND_SZ/REG_LINK
value with a byte slice, &s[..80]. The value is decoded from the memory
image and is attacker-controlled, so a multi-byte character straddling
byte 80 aborts the registry walk rather than previewing a value.
79 ASCII characters followed by U+4E16 puts byte 80 inside a 3-byte
character. This test fails on the current implementation:
end byte index 80 is not a char boundary; it is inside '世'
(bytes 79..82 of string)
The same defect class was already fixed once in this repo — see the
regression test at src/main.rs:7471, whose comment reads "it previously
byte-sliced &value[..77]".
RED commit: test only, no implementation change.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replace the &s[..80] byte slice with jsonguard::cap_display(s, 80). The fleet already publishes the char-safe truncation helper; this crate already depends on jsonguard. cap_display also drops control and bidi-override characters, which a preview rendered next to other evidence must never carry — a right-to-left override in a registry value reorders the analyst's view of neighbouring text. Truncation is now marked with U+2026 rather than three dots, matching the shared helper. format_data_preview_reg_sz_long_string_truncated is updated to that contract and now asserts the character count rather than the byte length, since the byte length of a truncated preview depends on the script it is written in. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
The defect
crates/memf-windows/src/registry_keys.rs:576truncated a decodedREG_SZ/REG_EXPAND_SZ/REG_LINKpreview with a byte slice:The value is decoded from the memory image, so it is attacker-controlled. A multi-byte character straddling byte 80 panics and aborts the registry walk rather than previewing a value:
Any non-Latin registry value — a Chinese, Japanese, Korean, Cyrillic, Arabic or emoji-bearing string — is a candidate, so this fires on ordinary non-English evidence long before anyone crafts it deliberately.
The repo has been bitten by this class before:
src/main.rs:7471carries a regression test whose comment reads "it previously byte-sliced&value[..77]".The fix
jsonguard::cap_display(s.as_str(), 80)— the fleet's char-safe truncation helper. This crate already depended onjsonguard; only thememf-windowsmember needed the dependency line.cap_displayalso drops control and bidi-override characters, which a preview rendered next to other evidence must never carry: a right-to-left override in a registry value reorders the analyst's view of neighbouring text.Commits
be64da9—"A".repeat(79) + "世界", which puts byte 80 inside a 3-byte character. Confirmed failing before the fix with the panic quoted above.34c08be— migrate tojsonguard::cap_display.One behaviour change
Truncation is now marked with
…(U+2026) rather than three dots, matching the shared helper.format_data_preview_reg_sz_long_string_truncatedis updated to that contract, and now asserts the character count rather than the byte length — the byte length of a truncated preview depends on the script it is written in, which is what made the old assertion misleading.Adoption note
jsonguard::cap_displayhad zero callers anywhere in the fleet before this change. The correct primitive was published and exported; two byte-slice truncations in this one repo went in around it.Gate
cargo build,cargo test --workspace(all suites, 0 failed),cargo clippy --all-targets -- -D warnings,cargo fmt --check— all clean.🤖 Generated with Claude Code