174 tests covering URL normalization, FTS5 query sanitization, SSRF/CSRF guards, sharing-mode logic, DB schema and upsert paths, handler end-to-end flows, and gateway body-size / mesh-whitelist guards. Each recent bug-fix commit (6ffd38d,1bc695f,8dffd8c) has an explicit regression test in test_regressions.py. One xfail documents a minor latent bug in clean_url where port 80 is not stripped from upgraded https URLs.
60 lines
1.7 KiB
Python
60 lines
1.7 KiB
Python
"""Tests for `_check_csrf` — form-submission CSRF protection.
|
|
|
|
Every POST handler calls this to verify the submitted _csrf field matches
|
|
the token stored in the thread-local (which is seeded from the cookie by
|
|
`dispatch_request`). Missing or mismatched tokens must fail closed.
|
|
"""
|
|
import handlers as handlers_module
|
|
from handlers import _check_csrf, _csrf_field, _get_csrf_token
|
|
|
|
|
|
def _set_token(token):
|
|
handlers_module._request_local.csrf_token = token
|
|
|
|
|
|
def _clear_token():
|
|
if hasattr(handlers_module._request_local, "csrf_token"):
|
|
del handlers_module._request_local.csrf_token
|
|
|
|
|
|
def teardown_function(_):
|
|
_clear_token()
|
|
|
|
|
|
def test_rejects_missing_token_in_body():
|
|
_set_token("server-side-token")
|
|
assert _check_csrf({}) is False
|
|
|
|
|
|
def test_rejects_empty_token_in_body():
|
|
_set_token("server-side-token")
|
|
assert _check_csrf({"_csrf": [""]}) is False
|
|
|
|
|
|
def test_rejects_mismatched_token():
|
|
_set_token("server-side-token")
|
|
assert _check_csrf({"_csrf": ["attacker-token"]}) is False
|
|
|
|
|
|
def test_accepts_matching_token():
|
|
_set_token("server-side-token")
|
|
assert _check_csrf({"_csrf": ["server-side-token"]}) is True
|
|
|
|
|
|
def test_rejects_when_server_token_missing():
|
|
"""If the server-side token is empty (shouldn't happen after dispatch_request
|
|
seeds it, but be defensive), the check must fail closed."""
|
|
_clear_token()
|
|
assert _check_csrf({"_csrf": ["anything"]}) is False
|
|
|
|
|
|
def test_csrf_field_renders_current_token():
|
|
_set_token("abc123")
|
|
field = _csrf_field()
|
|
assert 'name="_csrf"' in field
|
|
assert 'value="abc123"' in field
|
|
|
|
|
|
def test_get_csrf_token_returns_empty_when_unset():
|
|
_clear_token()
|
|
assert _get_csrf_token() == ""
|