From 3947cf343061575e2ff02fd41d89fe71abcb4839 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 7 May 2026 02:46:21 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20Denial=20of=20Service=20(DoS)=20vulnerability=20via=20?= =?UTF-8?q?large=20bytes=20input?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enforced strict length limits on `bytes` inputs in addition to `str` inputs before passing them to Python's `ipaddress.ip_address()` function to prevent CPU exhaustion DoS attacks due to inefficient internal parsing of extremely large byte objects. Co-authored-by: ManupaKDU <95234271+ManupaKDU@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ test_testping1.py | 10 +++++++++- testping1.py | 6 +++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 7d66386..d3e2b0a 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -71,3 +71,7 @@ **Vulnerability:** Argument Injection was possible because the dynamic string input was directly appended to the system utility (`ping`). If the string started with a hyphen (e.g., `-h` or other valid system binary flags), it would be treated as an option flag by the executable rather than the positional IP operand. **Learning:** Even when inputs are validated structurally or wrapped securely in Python list structures `['ping', ip]`, system executables parse them linearly. A string matching an option flag will alter the executable's behavior before it reaches positional processing. **Prevention:** To prevent Argument Injection, use `--` before dynamic string operands. This POSIX convention explicitly tells the program that subsequent arguments should be treated as positional arguments (operands) and not as options or flags, regardless of whether they begin with a hyphen. +## 2024-05-07 - Python ipaddress DoS via large bytes input +**Vulnerability:** Python's `ipaddress.ip_address()` function accepts both `str` and `bytes`. When passing an extremely large bytes object (e.g., `b"A" * 10**8`), the module can take several seconds to raise a `ValueError` due to inefficient internal parsing logic, leading to a CPU exhaustion Denial of Service (DoS). +**Learning:** Checking the length of `str` inputs before passing them to `ipaddress.ip_address()` is not sufficient to prevent DoS, as an attacker could pass a massive `bytes` object if the function accepts polymorphic types. +**Prevention:** Always enforce strict length limits (e.g., <= 100 characters/bytes) on *both* `str` and `bytes` inputs before attempting to parse them using the `ipaddress` module. Use `isinstance(ip, (str, bytes))` and check `len()`. diff --git a/test_testping1.py b/test_testping1.py index 1ec1442..653310a 100644 --- a/test_testping1.py +++ b/test_testping1.py @@ -32,7 +32,15 @@ def test_is_reachable_ip_too_long(self, mock_call): """Test is_reachable rejects overly long IP strings to prevent DoS.""" with self.assertLogs(level='ERROR') as log: self.assertFalse(is_reachable('A' * 101)) - self.assertIn("IP address string too long", log.output[0]) + self.assertIn("IP address input too long", log.output[0]) + mock_call.assert_not_called() + + @patch('testping1.subprocess.call') + def test_is_reachable_ip_bytes_too_long(self, mock_call): + """Test is_reachable rejects overly long IP bytes to prevent DoS.""" + with self.assertLogs(level='ERROR') as log: + self.assertFalse(is_reachable(b'A' * 101)) + self.assertIn("IP address input too long", log.output[0]) mock_call.assert_not_called() @patch('testping1.subprocess.call') diff --git a/testping1.py b/testping1.py index 8c5a23f..8502a12 100644 --- a/testping1.py +++ b/testping1.py @@ -55,9 +55,9 @@ def is_reachable(ip, timeout=1): return False # 🛡️ Sentinel: Add input length limit to prevent resource exhaustion (DoS) - # The ipaddress module can take significant time to parse extremely long strings - if isinstance(ip, str) and len(ip) > 100: - logging.error("IP address string too long") + # The ipaddress module can take significant time to parse extremely long strings or bytes + if isinstance(ip, (str, bytes)) and len(ip) > 100: + logging.error("IP address input too long") return False # 🛡️ Sentinel: Validate IP address to prevent argument injection