Skip to content

Commit 7c9aaa7

Browse files
sebastianMindeeianardee
authored andcommitted
⏪ revert URL safety checks (#455)
1 parent 0f678f5 commit 7c9aaa7

2 files changed

Lines changed: 1 addition & 133 deletions

File tree

‎mindee/mindee_http/response_validation.py‎

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import ipaddress
21
import json
32
from urllib.parse import urlparse
43

@@ -7,15 +6,12 @@
76
from mindee.error.mindee_error import MindeeSourceError
87
from mindee.parsing.common.string_dict import StringDict
98

10-
_CGNAT_BLOCK = ipaddress.IPv4Network("100.64.0.0/10")
11-
_IPV6_UNIQUE_LOCAL = ipaddress.IPv6Network("fc00::/7")
12-
139

1410
def validate_url_for_source(url: str) -> None:
1511
"""
1612
Validates that a URL is safe to send to the Mindee server.
1713
18-
Rejects any URL that could be used for Server-Side Request Forgery (SSRF).
14+
Rejects any URL that follow non-HTTPS schemes.
1915
2016
:param url: The URL string to validate.
2117
:raises MindeeSourceError: If the URL fails any security check.
@@ -28,42 +24,6 @@ def validate_url_for_source(url: str) -> None:
2824
if parsed.scheme.lower() != "https":
2925
raise MindeeSourceError("URL must be HTTPS")
3026

31-
if parsed.username or parsed.password:
32-
raise MindeeSourceError("Source URLs must not embed user credentials")
33-
34-
host = parsed.hostname
35-
if not host:
36-
raise MindeeSourceError("Source URL is missing a host")
37-
38-
lower_host = host.lower()
39-
if (
40-
lower_host == "localhost"
41-
or lower_host.endswith(".localhost")
42-
or lower_host == "ip6-localhost"
43-
or lower_host == "ip6-loopback"
44-
):
45-
raise MindeeSourceError(f"Loopback hostnames are not allowed: {host}")
46-
47-
try:
48-
addr = ipaddress.ip_address(lower_host)
49-
except ValueError:
50-
return
51-
52-
if (
53-
addr.is_loopback
54-
or addr.is_link_local
55-
or addr.is_private
56-
or addr.is_unspecified
57-
or addr.is_multicast
58-
):
59-
raise MindeeSourceError(f"URL host resolves to a disallowed address: {addr}")
60-
61-
if isinstance(addr, ipaddress.IPv4Address) and addr in _CGNAT_BLOCK:
62-
raise MindeeSourceError(f"URL host resolves to a disallowed address: {addr}")
63-
64-
if isinstance(addr, ipaddress.IPv6Address) and addr in _IPV6_UNIQUE_LOCAL:
65-
raise MindeeSourceError(f"URL host resolves to a disallowed address: {addr}")
66-
6727

6828
def is_valid_sync_response(response: httpx.Response) -> bool:
6929
"""

‎tests/v1/input/test_url_validation.py‎

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -15,95 +15,3 @@ def test_rejects_ftp(self):
1515

1616
def test_accepts_https(self):
1717
validate_url_for_source("https://example.com/file.pdf")
18-
19-
20-
class TestValidateUrlUserinfo:
21-
def test_rejects_username_and_password(self):
22-
with pytest.raises(MindeeSourceError, match="credentials"):
23-
validate_url_for_source("https://user:pass@example.com/file.pdf")
24-
25-
def test_rejects_username_only(self):
26-
with pytest.raises(MindeeSourceError, match="credentials"):
27-
validate_url_for_source("https://user@example.com/file.pdf")
28-
29-
30-
class TestValidateUrlLoopbackHostnames:
31-
def test_rejects_localhost(self):
32-
with pytest.raises(MindeeSourceError, match="Loopback"):
33-
validate_url_for_source("https://localhost/file.pdf")
34-
35-
def test_rejects_localhost_subdomain(self):
36-
with pytest.raises(MindeeSourceError, match="Loopback"):
37-
validate_url_for_source("https://myapp.localhost/file.pdf")
38-
39-
def test_rejects_ip6_localhost(self):
40-
with pytest.raises(MindeeSourceError, match="Loopback"):
41-
validate_url_for_source("https://ip6-localhost/file.pdf")
42-
43-
def test_rejects_ip6_loopback(self):
44-
with pytest.raises(MindeeSourceError, match="Loopback"):
45-
validate_url_for_source("https://ip6-loopback/file.pdf")
46-
47-
48-
class TestValidateUrlLoopbackIPs:
49-
def test_rejects_ipv4_loopback(self):
50-
with pytest.raises(MindeeSourceError, match="disallowed"):
51-
validate_url_for_source("https://127.0.0.1/file.pdf")
52-
53-
def test_rejects_ipv4_loopback_other(self):
54-
with pytest.raises(MindeeSourceError, match="disallowed"):
55-
validate_url_for_source("https://127.0.0.2/file.pdf")
56-
57-
def test_rejects_ipv6_loopback(self):
58-
with pytest.raises(MindeeSourceError, match="disallowed"):
59-
validate_url_for_source("https://[::1]/file.pdf")
60-
61-
62-
class TestValidateUrlPrivateIPs:
63-
def test_rejects_rfc1918_10_block(self):
64-
with pytest.raises(MindeeSourceError, match="disallowed"):
65-
validate_url_for_source("https://10.0.0.1/file.pdf")
66-
67-
def test_rejects_rfc1918_172_block(self):
68-
with pytest.raises(MindeeSourceError, match="disallowed"):
69-
validate_url_for_source("https://172.16.0.1/file.pdf")
70-
71-
def test_rejects_rfc1918_192_block(self):
72-
with pytest.raises(MindeeSourceError, match="disallowed"):
73-
validate_url_for_source("https://192.168.1.1/file.pdf")
74-
75-
def test_rejects_link_local(self):
76-
with pytest.raises(MindeeSourceError, match="disallowed"):
77-
validate_url_for_source("https://169.254.0.1/file.pdf")
78-
79-
def test_rejects_unspecified(self):
80-
with pytest.raises(MindeeSourceError, match="disallowed"):
81-
validate_url_for_source("https://0.0.0.0/file.pdf")
82-
83-
def test_rejects_multicast(self):
84-
with pytest.raises(MindeeSourceError, match="disallowed"):
85-
validate_url_for_source("https://224.0.0.1/file.pdf")
86-
87-
88-
class TestValidateUrlCgnat:
89-
def test_rejects_cgnat_start(self):
90-
with pytest.raises(MindeeSourceError, match="disallowed"):
91-
validate_url_for_source("https://100.64.0.1/file.pdf")
92-
93-
def test_rejects_cgnat_end(self):
94-
with pytest.raises(MindeeSourceError, match="disallowed"):
95-
validate_url_for_source("https://100.127.255.255/file.pdf")
96-
97-
def test_accepts_just_outside_cgnat(self):
98-
# 100.128.0.1 is outside 100.64.0.0/10
99-
validate_url_for_source("https://100.128.0.1/file.pdf")
100-
101-
102-
class TestValidateUrlIpv6UniqueLocal:
103-
def test_rejects_ipv6_ula_fc(self):
104-
with pytest.raises(MindeeSourceError, match="disallowed"):
105-
validate_url_for_source("https://[fc00::1]/file.pdf")
106-
107-
def test_rejects_ipv6_ula_fd(self):
108-
with pytest.raises(MindeeSourceError, match="disallowed"):
109-
validate_url_for_source("https://[fd00::1]/file.pdf")

0 commit comments

Comments
 (0)