Skip to content
Snippets Groups Projects
Unverified Commit f96b85ec authored by Brendan Abolivier's avatar Brendan Abolivier Committed by GitHub
Browse files

Ensure the type of URL attributes is always str when matching against preview blacklist (#12333)

parent c31c1091
No related branches found
No related tags found
No related merge requests found
Fix a long-standing bug affecting URL previews that would generate a 500 response instead of a 403 if the previewed URL includes a port that isn't allowed by the relevant blacklist.
......@@ -200,12 +200,17 @@ class PreviewUrlResource(DirectServeJsonResource):
match = False
continue
# Some attributes might not be parsed as strings by urlsplit (such as the
# port, which is parsed as an int). Because we use match functions that
# expect strings, we want to make sure that's what we give them.
value_str = str(value)
if pattern.startswith("^"):
if not re.match(pattern, getattr(url_tuple, attrib)):
if not re.match(pattern, value_str):
match = False
continue
else:
if not fnmatch.fnmatch(getattr(url_tuple, attrib), pattern):
if not fnmatch.fnmatch(value_str, pattern):
match = False
continue
if match:
......
......@@ -17,7 +17,7 @@ import json
import os
import re
from typing import Any, Dict, Optional, Sequence, Tuple, Type
from urllib.parse import urlencode
from urllib.parse import quote, urlencode
from twisted.internet._resolver import HostResolution
from twisted.internet.address import IPv4Address, IPv6Address
......@@ -69,7 +69,6 @@ class URLPreviewTests(unittest.HomeserverTestCase):
"2001:800::/21",
)
config["url_preview_ip_range_whitelist"] = ("1.1.1.1",)
config["url_preview_url_blacklist"] = []
config["url_preview_accept_language"] = [
"en-UK",
"en-US;q=0.9",
......@@ -1123,3 +1122,43 @@ class URLPreviewTests(unittest.HomeserverTestCase):
os.path.exists(path),
f"{os.path.relpath(path, self.media_store_path)} was not deleted",
)
@unittest.override_config({"url_preview_url_blacklist": [{"port": "*"}]})
def test_blacklist_port(self) -> None:
"""Tests that blacklisting URLs with a port makes previewing such URLs
fail with a 403 error and doesn't impact other previews.
"""
self.lookups["matrix.org"] = [(IPv4Address, "10.1.2.3")]
bad_url = quote("http://matrix.org:8888/foo")
good_url = quote("http://matrix.org/foo")
channel = self.make_request(
"GET",
"preview_url?url=" + bad_url,
shorthand=False,
await_result=False,
)
self.pump()
self.assertEqual(channel.code, 403, channel.result)
channel = self.make_request(
"GET",
"preview_url?url=" + good_url,
shorthand=False,
await_result=False,
)
self.pump()
client = self.reactor.tcpClients[0][2].buildProtocol(None)
server = AccumulatingProtocol()
server.makeConnection(FakeTransport(client, self.reactor))
client.makeConnection(FakeTransport(server, self.reactor))
client.dataReceived(
b"HTTP/1.0 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n"
% (len(self.end_content),)
+ self.end_content
)
self.pump()
self.assertEqual(channel.code, 200)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment