Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -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()`.
10 changes: 9 additions & 1 deletion test_testping1.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
6 changes: 3 additions & 3 deletions testping1.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading