Require real browser origins for escape grant minting (#4582)

This commit is contained in:
Rod Boev committed 2026-06-23 02:53:12 -04:00
1 parent decb1037bc
commit 40fc69b1cf
2 files changed
+21 -2

No files matched your search

+2 -2
View File
@@ -12949,8 +12949,8 @@ def _read_json_request_body(handler, *, max_bytes: int = 4096) -> dict:
def _handle_escape_authorize(handler, parsed, body: dict | None = None): def _handle_escape_authorize(handler, parsed, body: dict | None = None):
if handler.command != "POST": if handler.command != "POST":
return bad(handler, "method not allowed", 405) return bad(handler, "method not allowed", 405)
if not _is_browser_unsafe_request(handler): if not handler.headers.get("Origin"):
return bad(handler, "browser confirmation required", 403) return bad(handler, "browser origin required", 403)
if not _check_csrf(handler): if not _check_csrf(handler):
return bad(handler, _csrf_rejection_error(handler), 403) return bad(handler, _csrf_rejection_error(handler), 403)
if body is None: if body is None:
@@ -36,6 +36,11 @@ def _browser_headers() -> dict[str, str]:
return {"Origin": f"{parsed.scheme}://{parsed.netloc}"} return {"Origin": f"{parsed.scheme}://{parsed.netloc}"}
def _referer_only_headers() -> dict[str, str]:
parsed = urllib.parse.urlparse(BASE)
return {"Referer": f"{parsed.scheme}://{parsed.netloc}/workspace"}
def _post_json(path: str, body: dict | None = None, headers: dict[str, str] | None = None) -> tuple[dict, int]: def _post_json(path: str, body: dict | None = None, headers: dict[str, str] | None = None) -> tuple[dict, int]:
req = urllib.request.Request( req = urllib.request.Request(
BASE + path, BASE + path,
@@ -101,6 +106,13 @@ class TestIssue4582EscapeNavigationLive:
) )
assert denied_status == 403, denied assert denied_status == 403, denied
referer_only, referer_only_status = _post_json(
"/api/escape/authorize",
{"session_id": sid, "path": "escape-file.txt"},
headers=_referer_only_headers(),
)
assert referer_only_status == 403, referer_only
auth, status = _post_json( auth, status = _post_json(
"/api/escape/authorize", "/api/escape/authorize",
{"session_id": sid, "path": "escape-file.txt"}, {"session_id": sid, "path": "escape-file.txt"},
@@ -147,6 +159,13 @@ class TestIssue4582EscapeNavigationLive:
denied, denied_status = _post_json("/api/escape/authorize", {"session_id": sid, "path": "escape"}) denied, denied_status = _post_json("/api/escape/authorize", {"session_id": sid, "path": "escape"})
assert denied_status == 403, denied assert denied_status == 403, denied
referer_only, referer_only_status = _post_json(
"/api/escape/authorize",
{"session_id": sid, "path": "escape"},
headers=_referer_only_headers(),
)
assert referer_only_status == 403, referer_only
auth, status = _post_json( auth, status = _post_json(
"/api/escape/authorize", "/api/escape/authorize",
{"session_id": sid, "path": "escape"}, {"session_id": sid, "path": "escape"},