Skip to content

Commit d0c9333

Browse files
committed
fix: add octal integer IP parsing and fix test naming
- Add octal integer format parsing (017700000001 = 127.0.0.1) - Rename SSL test to reflect fail-secure behavior (stays_enabled, not defaults_to_false) - Add tests for octal integer IP obfuscation
1 parent 4475d77 commit d0c9333

2 files changed

Lines changed: 17 additions & 3 deletions

File tree

src/fetch/src/mcp_server_fetch/server.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,25 @@ def _parse_obfuscated_ip(hostname: str) -> str | None:
7979
8080
Attackers may use alternative IP representations to bypass SSRF filters:
8181
- Decimal: 2130706433 (= 127.0.0.1)
82-
- Octal: 0177.0.0.1 (= 127.0.0.1)
82+
- Octal integer: 017700000001 (= 127.0.0.1)
83+
- Octal dotted: 0177.0.0.1 (= 127.0.0.1)
8384
- Hex: 0x7f000001 (= 127.0.0.1)
8485
- Mixed: 0x7f.0.0.1 (= 127.0.0.1)
8586
8687
Returns the normalized IP string if detected, None otherwise.
8788
"""
8889
hostname = hostname.strip()
8990

91+
# Try octal integer format (e.g., 017700000001 = 127.0.0.1)
92+
# Must check before decimal since octal strings are also digits
93+
try:
94+
if hostname.startswith("0") and len(hostname) > 1 and hostname.isdigit():
95+
ip_int = int(hostname, 8)
96+
if 0 <= ip_int <= 0xFFFFFFFF: # Valid 32-bit range
97+
return str(ipaddress.IPv4Address(ip_int))
98+
except (ValueError, ipaddress.AddressValueError):
99+
pass
100+
90101
# Try decimal integer format (e.g., 2130706433 = 127.0.0.1)
91102
try:
92103
if hostname.isdigit():

src/fetch/tests/test_security.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ async def test_ssl_verify_case_insensitive(self, reset_env):
114114
assert server_module.SSL_VERIFY is expected, f"Failed for value: {value}"
115115

116116
@pytest.mark.asyncio
117-
async def test_ssl_verify_invalid_value_defaults_to_false(self, reset_env):
118-
"""Invalid values should default to False (not 'true')."""
117+
async def test_ssl_verify_invalid_value_stays_enabled(self, reset_env):
118+
"""Invalid/unknown values should keep SSL verification ENABLED (fail-secure)."""
119119
os.environ['MCP_FETCH_SSL_VERIFY'] = 'invalid'
120120

121121
import importlib
@@ -176,6 +176,9 @@ class TestIPObfuscationParsing:
176176
# Hex encoding
177177
("0x7f000001", "127.0.0.1"),
178178
("0x7F000001", "127.0.0.1"), # uppercase
179+
# Octal integer format (without dots)
180+
("017700000001", "127.0.0.1"),
181+
("025177524776", "169.254.169.254"), # metadata IP in octal
179182
# Octal dotted format
180183
("0177.0.0.1", "127.0.0.1"),
181184
("0177.0.0.01", "127.0.0.1"),

0 commit comments

Comments
 (0)