Block open redirect via backslash in redirect Location

The leading-slash collapse added for #2429 only stripped forward
slashes, so a path like /\example.com/ (or its %5C-encoded form) was
redirected to Location: /\example.com. Browsers treat a backslash as a
slash, so that resolves to //example.com and then https://example.com,
re-opening the open redirect.

Collapse leading backslashes as well as slashes. Extends the existing
slash-slash test to cover /\example.com/ and /\/example.com/.

Fixes #2680
This commit is contained in:
ATOM00blue 2026-05-22 06:34:22 +05:30
commit 9fbd31df00
2 changed files with 18 additions and 6 deletions

View file

@ -99,8 +99,18 @@ def test_custom_route_pattern_404(custom_pages_client):
assert ">Oh no</" in response.text
def test_custom_route_pattern_with_slash_slash_302(custom_pages_client):
# https://github.com/simonw/datasette/issues/2429
response = custom_pages_client.get("//example.com/")
@pytest.mark.parametrize(
"path",
(
# https://github.com/simonw/datasette/issues/2429
"//example.com/",
# https://github.com/simonw/datasette/issues/2680
# Browsers treat backslashes as slashes, so these are also open redirects
"/\\example.com/",
"/\\/example.com/",
),
)
def test_custom_route_pattern_open_redirect_302(custom_pages_client, path):
response = custom_pages_client.get(path)
assert response.status == 302
assert response.headers["location"] == "/example.com"