From 35f0153bb42a4faf135ba9c5c981592300f29b31 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 16 May 2026 02:40:11 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[security?= =?UTF-8?q?=20improvement]=20Limit=20IPv6=20scope=5Fid=20length=20and=20ch?= =?UTF-8?q?arset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Enhance `SCOPE_ID_REGEX` to strictly limit IPv6 `scope_id` lengths to 15 characters, mapping to standard Linux `IFNAMSIZ` boundaries. - Explicitly define the regex character set (`[a-zA-Z0-9_\-]`) to prevent edge cases with arbitrarily long or Unicode-based `scope_id` payloads. - Added tests to ensure long interface identifiers are correctly rejected before OS execution. Co-authored-by: ManupaKDU <95234271+ManupaKDU@users.noreply.github.com> --- test_testping1.py | 13 +++++++++++++ testping1.py | 4 +++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/test_testping1.py b/test_testping1.py index a3fcd04..622fbbd 100644 --- a/test_testping1.py +++ b/test_testping1.py @@ -246,6 +246,19 @@ def test_is_reachable_ipv6_scope_id_validation(self, mock_call): self.assertIn("Invalid IPv6 scope ID: IPv6Address('fe80::1%eth0\\nERROR:root:Compromised')", log.output[0]) mock_call.assert_not_called() + @patch('testping1.subprocess.call') + def test_is_reachable_ipv6_scope_id_length_limit(self, mock_call): + """Test is_reachable enforces strict length limit on IPv6 scope IDs.""" + import ipaddress + # Max Linux IFNAMSIZ is 15. Provide 16 chars. + malicious_ip_obj = ipaddress.IPv6Address('fe80::1') + malicious_ip_obj._scope_id = 'a' * 16 + + with self.assertLogs(level='ERROR') as log: + self.assertFalse(is_reachable(malicious_ip_obj)) + self.assertIn("Invalid IPv6 scope ID:", log.output[0]) + mock_call.assert_not_called() + @patch('testping1.subprocess.call') def test_is_reachable_subprocess_timeout(self, mock_call): """Test is_reachable handles subprocess.TimeoutExpired securely.""" diff --git a/testping1.py b/testping1.py index 63e23a5..9393a6b 100644 --- a/testping1.py +++ b/testping1.py @@ -15,7 +15,9 @@ # Calling re.compile() once at module load avoids the overhead of parsing and compiling # the regular expression (or looking it up in the internal cache) during every is_reachable() execution. # This yields a measurable CPU speedup when firing thousands of concurrent pings. -SCOPE_ID_REGEX = re.compile(r'[\w\-]+') +# 🛡️ Sentinel: Enforce strict length limits (1-15 chars) and explicit ASCII charset +# to prevent resource exhaustion or unexpected OS behavior from overly long/Unicode scope IDs. +SCOPE_ID_REGEX = re.compile(r'[a-zA-Z0-9_\-]{1,15}') # ⚡ Bolt: Cache the absolute path of the ping executable. # Calling shutil.which() once at module load avoids the overhead of traversing