Skip to content

mask_pii leaves the trailing digits of an international phone number (+90 532 123 45 67 becomes [REDACTED] 67) #1051

Open

Description

@cemililik

Summary

mask_pii leaves the trailing digits of an international phone number in the text: +90 532 123 45 67 becomes [REDACTED] 67. The phone pattern in forgelm/data_audit/_pii_regex.py matches a + country code followed by at most three digit groups of 2-4 digits and a final optional group of up to 4 digits, so a number written in five or more groups is only partly consumed. The remaining digits are still part of a phone number a person could be re-identified from.

Evidence

>>> from forgelm.data_audit import mask_pii
>>> mask_pii("Call +90 532 123 45 67 now")
'Call [REDACTED] 67 now'

The user manual's masking example (docs/usermanuals/{en,tr}/data/pii-masking.md) shows the same output and warns that the pattern "does not always consume the full number". The GDPR documentation tells operators that masking removes only the formats it detects; a half-masked phone number is the case where an operator would expect it to work.

Why it matters

forgelm ingest --pii-mask is the only built-in masking step. A corpus masked with it can still contain the last digits of numbers the operator believes are gone, and forgelm audit runs the same pattern, so it does not report them either.

Acceptance criteria

  • Numbers written with a + country code and 2-6 digit groups separated by spaces, dots or hyphens are masked completely. At minimum: +90 532 123 45 67, +1 415 555 0132, +44 20 7946 0958, +49 151 23456789, +33 1 23 45 67 89.
  • The parenthesised-area-code form (555) 123-4567 keeps working.
  • No new false positives on timestamps, ISO dates, version strings and log line numbers (the existing phone tests stay green and gain these cases).
  • The pattern stays linear: it passes TestPiiRegexLinearity and the rules in docs/standards/regex.md (bounded quantifiers, no two quantifiers over the same characters).
  • The "Before / After" example and the warning in docs/usermanuals/{en,tr}/data/pii-masking.md are updated to the new behaviour.

Context

Found while correcting the PII-masking documentation for #101. Related: #507 (phone numbers also trip the credit-card detector), #547 (module sweep: dataset audit).

Activity

  1. added
    bugSomething isn't working
    severity: mediumReal defect with limited reach or a workaround
    wave: 3Roadmap wave 3: medium severity, module sweeps
    on Oct 22, 2026
  2. added
    needs-triageNot triaged yet: every new issue starts with it; only a maintainer removes it
    on Oct 22, 2026
  3. cemililik commented on Oct 22, 2026

    @cemililik
    CollaboratorAuthor

    Triage (2026-10-22): accepted. Medium · Wave 3 · parent #870 (Wave 3 · Module sweep).

    Reproduced on development at 735a02f (mask_pii("Call <number> now")):

    Input Output
    +90 532 123 45 67 [REDACTED] 67
    +90-532-123-45-67 [REDACTED]-67
    +90.532.123.45.67 [REDACTED].67
    +33 1 23 45 67 89 unchanged, not detected at all
    +1 415 555 0132, +44 20 7946 0958, +49 151 23456789, (555) 123-4567 fully masked

    The French case is worse than the title suggests: the pattern needs 2-4 digits after the country code, so a one-digit area code is never matched. The acceptance criteria already cover it.

    Not a duplicate. Related records:

    Not a security advisory: the residue is already documented in the public manual, and nobody has to attack anything to get it. No newcomer label, because the change needs the regex standard's linearity rules (docs/standards/regex.md) and the PII regression set.

  4. removed
    needs-triageNot triaged yet: every new issue starts with it; only a maintainer removes it
    on Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: data-auditCode area: data-auditbugSomething isn't workingseverity: mediumReal defect with limited reach or a workaroundwave: 3Roadmap wave 3: medium severity, module sweeps

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions