From a161425858f140bffc234c1aa5a2e1a74e8d8e25 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 02:18:39 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[MEDIUM]=20?= =?UTF-8?q?Fix=20DoS=20via=20bytes=20bypass=20in=20timeout=20validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated timeout validation in `testping1.py` to check for `isinstance(timeout, (str, bytes))` instead of just `str` to prevent massive bytes objects from bypassing length checks and causing CPU exhaustion during `int()` conversion. - Updated `test_testping1.py` assertion strings and added explicit test case for byte payload DoS. Co-authored-by: ManupaKDU <95234271+ManupaKDU@users.noreply.github.com> --- test_testping1.py | 16 ++++++++++++---- testping1.py | 4 ++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/test_testping1.py b/test_testping1.py index 653310a..9f39c61 100644 --- a/test_testping1.py +++ b/test_testping1.py @@ -48,7 +48,15 @@ def test_is_reachable_timeout_too_long(self, mock_call): """Test is_reachable rejects overly long timeout strings to prevent DoS.""" with self.assertLogs(level='ERROR') as log: self.assertFalse(is_reachable('8.8.8.8', timeout='A' * 101)) - self.assertIn("Timeout string too long", log.output[0]) + self.assertIn("Timeout input too long", log.output[0]) + mock_call.assert_not_called() + + @patch('testping1.subprocess.call') + def test_is_reachable_timeout_bytes_too_long(self, mock_call): + """Test is_reachable rejects overly long timeout bytes to prevent DoS.""" + with self.assertLogs(level='ERROR') as log: + self.assertFalse(is_reachable('8.8.8.8', timeout=b'1' * 101)) + self.assertIn("Timeout input too long", log.output[0]) mock_call.assert_not_called() @patch('testping1.subprocess.call') @@ -112,11 +120,11 @@ def test_is_reachable_invalid_timeout(self, mock_call): mock_call.assert_not_called() @patch('testping1.subprocess.call') - def test_is_reachable_timeout_too_long(self, mock_call): - """Test is_reachable rejects overly long timeout strings to prevent DoS.""" + def test_is_reachable_timeout_too_long_numeric_string(self, mock_call): + """Test is_reachable rejects overly long numeric timeout strings to prevent DoS.""" with self.assertLogs(level='ERROR') as log: self.assertFalse(is_reachable('8.8.8.8', timeout='1' * 101)) - self.assertIn("Timeout string too long", log.output[0]) + self.assertIn("Timeout input too long", log.output[0]) mock_call.assert_not_called() @patch('testping1.subprocess.call') diff --git a/testping1.py b/testping1.py index 8502a12..82304b9 100644 --- a/testping1.py +++ b/testping1.py @@ -157,8 +157,8 @@ def is_reachable(ip, timeout=1): else: # 🛡️ Sentinel: Validate timeout length to prevent CPU exhaustion (DoS) # Python's int() conversion for massive strings has O(N^2) complexity. - if isinstance(timeout, str) and len(timeout) > 100: - logging.error("Timeout string too long") + if isinstance(timeout, (str, bytes)) and len(timeout) > 100: + logging.error("Timeout input too long") return False try: