mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Move open redirect fix to asgi_send_redirect, refs #2429
See https://github.com/simonw/datasette/pull/2500#issuecomment-3488632278
This commit is contained in:
parent
c1dd2c1dfb
commit
0403a04da6
3 changed files with 7 additions and 7 deletions
|
|
@ -1391,11 +1391,6 @@ class DatasetteRouter:
|
||||||
context = {}
|
context = {}
|
||||||
if path.endswith(b"/"):
|
if path.endswith(b"/"):
|
||||||
path = path.rstrip(b"/")
|
path = path.rstrip(b"/")
|
||||||
|
|
||||||
# If you redirect with a // at the beginning, you end up with an open redirect, so
|
|
||||||
# https://my.site//foo/ - will redirect to https://foo
|
|
||||||
path = re.sub(rb"^/+", b"/", path)
|
|
||||||
|
|
||||||
if request.scope["query_string"]:
|
if request.scope["query_string"]:
|
||||||
path += b"?" + request.scope["query_string"]
|
path += b"?" + request.scope["query_string"]
|
||||||
await asgi_send_redirect(send, path.decode("latin1"))
|
await asgi_send_redirect(send, path.decode("latin1"))
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ from pathlib import Path
|
||||||
from http.cookies import SimpleCookie, Morsel
|
from http.cookies import SimpleCookie, Morsel
|
||||||
import aiofiles
|
import aiofiles
|
||||||
import aiofiles.os
|
import aiofiles.os
|
||||||
|
import re
|
||||||
|
|
||||||
# Workaround for adding samesite support to pre 3.8 python
|
# Workaround for adding samesite support to pre 3.8 python
|
||||||
Morsel._reserved["samesite"] = "SameSite"
|
Morsel._reserved["samesite"] = "SameSite"
|
||||||
|
|
@ -227,6 +228,9 @@ async def asgi_send_html(send, html, status=200, headers=None):
|
||||||
|
|
||||||
|
|
||||||
async def asgi_send_redirect(send, location, status=302):
|
async def asgi_send_redirect(send, location, status=302):
|
||||||
|
# Prevent open redirect vulnerability: strip multiple leading slashes
|
||||||
|
# //example.com would be interpreted as a protocol-relative URL (e.g., https://example.com/)
|
||||||
|
location = re.sub(r"^/+", "/", location)
|
||||||
await asgi_send(
|
await asgi_send(
|
||||||
send,
|
send,
|
||||||
"",
|
"",
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ def test_custom_route_pattern_404(custom_pages_client):
|
||||||
|
|
||||||
|
|
||||||
def test_custom_route_pattern_with_slash_slash_302(custom_pages_client):
|
def test_custom_route_pattern_with_slash_slash_302(custom_pages_client):
|
||||||
response = custom_pages_client.get("//nastyOpenRedirect/")
|
# https://github.com/simonw/datasette/issues/2429
|
||||||
|
response = custom_pages_client.get("//example.com/")
|
||||||
assert response.status == 302
|
assert response.status == 302
|
||||||
assert response.headers["location"] == "/nastyOpenRedirect"
|
assert response.headers["location"] == "/example.com"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue