Repository navigation
fix(safety): judge a card run as a unit and keep an adjacent CVV beside it - #278
Open
shaurya703 wants to merge 1 commit into
Open
shaurya703 wants to merge 1 commit into
shaurya703 wants to merge 1 commit into
Conversation
…de it The card rule capped its match at 19 digits and ended on a word boundary, so `4111 1111 1111 1111 003-1` matched on its Luhn-valid 19-digit head and was redacted in part, while `4111 1111 1111 1111 123` swallowed the CVV group into the candidate, failed Luhn at 19 digits and was neither detected nor redacted. The pattern now has no upper bound, so it consumes the whole run of digits and single separators, and `is_complete_card` judges that run as a unit: a complete PAN of 13–19 Luhn-valid digits, or such a PAN followed by one adjacent group of 3–4 digits after the last separator, the way a CVV is written next to its card. Anything else — a run that continues past 19 digits, or past one CVV group — is not a card at all, so an overlong candidate is left exactly as written rather than matched on a head that happens to pass Luhn. A detected span is counted once and redacted whole, CVV group included. A labelled CVV ends the run at the card, which is judged on its own. IPv4 validation is untouched. Closes tinyhumansai#262
Tiny Sweeper reviewTiny Sweeper completed its review; deterministic results follow. State: Incomplete Review snapshot
Completeness: Incomplete Features
Tests
FindingsNo active actionable findings. Could not review: crates/tinymemory-api/src/safety/mod_tests.rs, crates/tinymemory-api/src/safety/rules.rs Before merge
How this fits togetherflowchart LR
n0["...entifiers_replaces_structured_values_only<br/>changed"]:::changed
n1["build_rules<br/>changed"]:::changed
n2["Rule"]:::impacted
n3["redact_identifiers"]:::impacted
n4["PiiCategory"]:::impacted
n5["compile_builtin"]:::impacted
n6["keyword_rule"]:::impacted
n0 -->|calls| n3
n0 -->|tests| n3
n1 -->|uses| n2
n2 -->|uses| n4
n6 -->|uses| n2
n6 -->|uses| n4
n6 -->|calls| n5
classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Agent review detailscritique
security
tests
commits
description
Evidence and run details
|
There was a problem hiding this comment.
tinysweeper found nothing blocking, but could not review everything, so this is not an approval: crates/tinymemory-api/src/safety/mod_tests.rs, crates/tinymemory-api/src/safety/rules.rs.
$0.0019 · 75,818 in / 7,160 out · 0 cached (0%) · ladder/vectors-oai3, glm-5.3-flash · 369 embedded
security: $0.0004 · 43,968 in / 1,102 out · 0 cached (0%) · glm-5.3-flash
tests: $0.0002 · 16,364 in / 2,184 out · 0 cached (0%) · glm-5.3-flash
description: $0.0001 · 8,615 in / 11 out · 0 cached (0%) · glm-5.3-flash
This branch has not been deployed
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.
Summary
The card rule capped its match at 19 digits and ended on a word boundary, which left the card's boundary to wherever Luhn happened to pass:
4111 1111 1111 1111 003-1matched on its Luhn-valid 19-digit head, scanned as High/CreditCard, and was redacted in part ([redacted]-1).4111 1111 1111 1111 123swallowed the CVV group into the candidate, failed Luhn at 19 digits, scanned as None and came back from redaction unchanged.The pattern now has no upper bound (
\b\d(?:[ -]?\d){12,}\b), so it consumes the whole run of digits and single separators, and a new validatoris_complete_cardjudges that run as a unit. This is the same shape as the international phone fix in #265: the regex finds the run, the validator decides.Semantics
A run of digits with at most one space or hyphen between any two of them is a card when, and only when, it is complete as written:
4111 1111 1111 1111,4111111111111111, and4111 1111 1111 1111 003, which is a Luhn-valid 19-digit PAN as written).4111 1111 1111 1111 123,4111-1111-1111-1111-1234). The CVV is set beside the PAN, not folded into the Luhn check.4111 1111 1111 1111 003-1,4111 1111 1111 1111 1111 1111,41111111111111110031), is rejected whole. An overlong candidate is left exactly as written rather than matched on a head that happens to pass Luhn.A detected span is counted once and redacted whole, CVV group included (
pay with [redacted] today). A labelled CVV (4111 1111 1111 1111 cvv 123) ends the run at the card, which is judged on its own; the bare123after the label is not a structured identifier and stays. An ungrouped 19-digit run with a CVV glued on has no separator to split at and is rejected, since there is no way to tell PAN from CVV in it.IPv4 validation (
is_ipv4) is untouched;is_luhn_validis unchanged and now backsis_complete_card.Related issue
Closes #262
API or behavior changes
No public API change. Behavior change in the local detector (
local-safetyfeature): a card followed by an unlabelled 3–4 digit group now scans as CreditCard and the whole span is redacted; a Luhn-valid head of a longer digit run is no longer counted or partially redacted. Not breaking.Validation
Commands actually run, with their outcome:
cargo fmt --all -- --check– cleancargo clippy -p tinymemory-api --all-targets --all-features -- -D warnings– cleancargo test -p tinymemory-api --features local-safety -- safety– 38 passedcargo test -p tinymemory-api --all-features– 137 lib tests passed, all integration tests passedTests
Added to
crates/tinymemory-api/src/safety/mod_tests.rs:detects_card_with_adjacent_cvv_group– space- and hyphen-separated PAN + 3/4-digit CVV scan as High/CreditCard, count 1.detects_card_with_labelled_cvv– a label between card and CVV ends the run at the card; counted once.overlong_card_candidate_is_not_matched_on_its_head– the issue's003-1example plus 24-digit grouped, 20-digit ungrouped and 2-digit-tail runs produce no CreditCard hit.complete_card_validator_accepts_pan_or_pan_with_cvv_group– unit cases foris_complete_card: complete PAN, PAN + CVV, Luhn-valid 19-digit run, Luhn-invalid PAN with CVV tail, tails that are too short, too long or ungrouped.redact_identifiers_replaces_the_whole_card_span– PAN + CVV is replaced as one span; labelled CVV leaves only the card replaced.redact_identifiers_leaves_an_overlong_card_candidate_whole– no partial replacement of a Luhn-valid head.Existing card, Luhn, IPv4 and redaction tests pass unchanged.
Documentation
Rule comment and
is_complete_carddoc comment inrules.rsdescribe the grouping and adjacent-CVV semantics. The README's inherited-limitations paragraph still lists #262 alongside #260/#261/#263; left as is to match the sibling PRs (#265, #267, #268) and avoid four PRs editing the same sentence.Checklist
#[allow(...)],#[ignore], or relaxed lints.envcontents in the diff or the descriptionSummary by CodeRabbit