fix(webhooks): escape HTML in error responses, compare bearer as bytes
Address the two Security findings from PR review: - webhook_receiver: encode Authorization header and expected bearer to utf-8 bytes before hmac.compare_digest. Conventional form; doesn't rely on Python's implicit ASCII encoding. - webhook_routes: html.escape user-influenced and exception-derived strings before interpolating into HTMLResponse content. Covers the preset_id path param echoed in the "Unknown preset" branch and the str(e) text rendered on handler exceptions. Adds regression tests verifying compare_digest is invoked on bytes and that <script> payloads (in preset_id and exception messages) are emitted as escaped entities, not active markup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
c1368b9a7f
commit
4a3857aabb
@@ -272,3 +272,28 @@ def test_secret_unset_accepts_unauthenticated(monkeypatch):
|
||||
|
||||
assert response.status_code == 200
|
||||
assert receive_stream.receive_nowait().doc_id == "437"
|
||||
|
||||
|
||||
def test_compare_digest_is_called_with_bytes(monkeypatch, mocker):
|
||||
"""Regression: secret comparison must run on bytes, not strings, so
|
||||
that future non-ASCII secret support doesn't depend on Python's
|
||||
implicit ASCII encoding."""
|
||||
_patch_secret(monkeypatch, "supersecret")
|
||||
spy = mocker.spy(webhook_receiver.hmac, "compare_digest")
|
||||
|
||||
send_stream, _receive = anyio.create_memory_object_stream(max_buffer_size=4)
|
||||
app = _make_app(send_stream=send_stream)
|
||||
|
||||
with TestClient(app) as client:
|
||||
response = client.post(
|
||||
"/webhooks/nextcloud",
|
||||
json=_NOTE_CREATED,
|
||||
headers={"Authorization": "Bearer supersecret"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert spy.call_count == 1
|
||||
provided_arg, expected_arg = spy.call_args.args
|
||||
assert isinstance(provided_arg, bytes)
|
||||
assert isinstance(expected_arg, bytes)
|
||||
assert expected_arg == b"Bearer supersecret"
|
||||
|
||||
Reference in New Issue
Block a user