diff --git a/ods/extensions/services/privacy-shield/pii_scrubber.py b/ods/extensions/services/privacy-shield/pii_scrubber.py index d17c60183..7d64b2eb1 100644 --- a/ods/extensions/services/privacy-shield/pii_scrubber.py +++ b/ods/extensions/services/privacy-shield/pii_scrubber.py @@ -5,6 +5,7 @@ """ import codecs +import ipaddress import re import hashlib import secrets @@ -95,6 +96,15 @@ def scrub(self, text: str) -> str: if pii_type == 'credit_card' and not self._luhn_check(match): continue + # The regex identifies IPv4/IPv6-shaped candidates, but it + # deliberately does not encode numeric range rules. Avoid + # scrubbing version-like values such as 999.999.999.999. + if pii_type == 'ip_address': + try: + ipaddress.ip_address(match) + except ValueError: + continue + # Check if we've seen this PII before existing_token = None for token, original in self.pii_map.items(): diff --git a/ods/extensions/services/privacy-shield/tests/test_pii_scrubber.py b/ods/extensions/services/privacy-shield/tests/test_pii_scrubber.py index b9cd314ee..ab1b5a519 100644 --- a/ods/extensions/services/privacy-shield/tests/test_pii_scrubber.py +++ b/ods/extensions/services/privacy-shield/tests/test_pii_scrubber.py @@ -145,6 +145,13 @@ def test_compressed_ipv6_round_trips(self, detector): def test_clock_time_is_not_an_ip(self, detector): result = detector.scrub("Started at 12:34:56 UTC") assert "