Skip to content

Mask operator accepts an empty masking_char and deletes the masked characters #2486

Open

Description

@1AbdullahButt

Describe the bug
The mask operator accepts an empty masking_char. Validation only rejects values longer than one character, so "" passes. operate then builds "" * chars_to_mask + text[chars_to_mask:], so the masked characters are deleted, not masked. The output is shorter than the input and keeps the unmasked part of the value.

Code:

if len(masking_char) > 1:
raise InvalidParamError(
f"Invalid input, {self.MASKING_CHAR} must be a character"
)

To Reproduce
On main (aa77b9f):

from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import OperatorConfig, RecognizerResult

result = AnonymizerEngine().anonymize(
    "My card 4111111111111111 ok",
    [RecognizerResult("CREDIT_CARD", 8, 24, 1.0)],
    {"CREDIT_CARD": OperatorConfig(
        "mask", {"masking_char": "", "chars_to_mask": 12, "from_end": False}
    )},
)
print(repr(result.text))  # 'My card 1111 ok'

Expected behavior
InvalidParamError, like for a masking_char of two characters ("masking_char must be a character").

Actual behavior
No error. The first 12 digits are removed and the result is 'My card 1111 ok'.

Additional context
The check is len(masking_char) > 1; len(masking_char) != 1 would cover the empty string too. The same request through the anonymizer REST API ("masking_char": "") behaves the same way.

I have a fix with a regression test and will open a PR.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions