Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Ensure the type of URL attributes is always str when matching against…
Browse files Browse the repository at this point in the history
… preview blacklist (#12333)
  • Loading branch information
babolivier committed Mar 31, 2022
1 parent c31c109 commit f96b85e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
1 change: 1 addition & 0 deletions changelog.d/12333.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
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.
9 changes: 7 additions & 2 deletions synapse/rest/media/v1/preview_url_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,17 @@ async def _async_render_GET(self, request: SynapseRequest) -> None:
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:
Expand Down
43 changes: 41 additions & 2 deletions tests/rest/media/v1/test_url_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
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
Expand Down Expand Up @@ -69,7 +69,6 @@ def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer:
"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",
Expand Down Expand Up @@ -1123,3 +1122,43 @@ def test_cache_expiry(self) -> None:
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 comments on commit f96b85e

Please sign in to comment.