From 648fa7080d472ca1070dbe1ae5728d5ef00b4a86 Mon Sep 17 00:00:00 2001 From: Tang Vu <145498528+tang-vu@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:10:12 +0700 Subject: [PATCH] fix(privacy): validate IP address candidates --- ods/extensions/services/privacy-shield/pii_scrubber.py | 10 ++++++++++ .../services/privacy-shield/tests/test_pii_scrubber.py | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/ods/extensions/services/privacy-shield/pii_scrubber.py b/ods/extensions/services/privacy-shield/pii_scrubber.py index a6c908faf..005e577cb 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 @@ -87,6 +88,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 14a632433..9ac03c4b8 100644 --- a/ods/extensions/services/privacy-shield/tests/test_pii_scrubber.py +++ b/ods/extensions/services/privacy-shield/tests/test_pii_scrubber.py @@ -117,6 +117,15 @@ def test_full_ipv6(self, detector): result = detector.scrub(text) assert "2001:0db8:85a3:0000:0000:8a2e:0370:7334" not in result + @pytest.mark.parametrize( + "candidate", + ["999.999.999.999", "256.1.1.1", "192.168.1.999"], + ) + def test_invalid_ipv4_candidate_is_not_scrubbed(self, detector, candidate): + text = f"Version-like value: {candidate}" + + assert detector.scrub(text) == text + # ── API key detection ────────────────────────────────────────────────────────