fix(auth): normalize cookbook internal header whitespace

This commit is contained in:
RaresKeY 2026-07-21 17:57:42 +00:00
parent c540bf7269
commit fc83e56d3c
2 changed files with 32 additions and 1 deletions

View file

@ -66,8 +66,15 @@ def _header_values(headers, name: str) -> list[str]:
def _internal_header_matches(value: str) -> bool: def _internal_header_matches(value: str) -> bool:
"""Compare raw or proxy-combined values without obs-text type failures.""" """Compare raw or proxy-combined values without obs-text type failures."""
candidates = [value] candidates = [value]
trimmed_value = value.strip(" \t")
if trimmed_value != value:
candidates.append(trimmed_value)
if "," in value: if "," in value:
candidates.extend(part.strip() for part in value.split(",")) for part in value.split(","):
candidates.append(part)
trimmed_part = part.strip(" \t")
if trimmed_part != part:
candidates.append(trimmed_part)
try: try:
expected = INTERNAL_TOOL_TOKEN.encode("utf-8") expected = INTERNAL_TOOL_TOKEN.encode("utf-8")
except (AttributeError, UnicodeError): except (AttributeError, UnicodeError):

View file

@ -12,6 +12,7 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from starlette.middleware.base import BaseHTTPMiddleware from starlette.middleware.base import BaseHTTPMiddleware
import core.middleware as middleware
from core.middleware import ( from core.middleware import (
CodexCookbookBoundaryMiddleware, CodexCookbookBoundaryMiddleware,
INTERNAL_TOOL_HEADER, INTERNAL_TOOL_HEADER,
@ -123,6 +124,22 @@ DUPLICATE_PRE_BODY_HEADERS = [
[(_INTERNAL_HEADER_BYTES, b"invalid, " + _INTERNAL_TOKEN_BYTES)], [(_INTERNAL_HEADER_BYTES, b"invalid, " + _INTERNAL_TOKEN_BYTES)],
id="internal-proxy-combined", id="internal-proxy-combined",
), ),
pytest.param(
[(_INTERNAL_HEADER_BYTES, b" " + _INTERNAL_TOKEN_BYTES)],
id="internal-leading-sp",
),
pytest.param(
[(_INTERNAL_HEADER_BYTES, _INTERNAL_TOKEN_BYTES + b" ")],
id="internal-trailing-sp",
),
pytest.param(
[(_INTERNAL_HEADER_BYTES, b" " + _INTERNAL_TOKEN_BYTES + b" ")],
id="internal-both-sp",
),
pytest.param(
[(_INTERNAL_HEADER_BYTES, b"\t" + _INTERNAL_TOKEN_BYTES + b"\t")],
id="internal-both-htab",
),
pytest.param( pytest.param(
[ [
(_INTERNAL_HEADER_BYTES, b"\xff"), (_INTERNAL_HEADER_BYTES, b"\xff"),
@ -291,6 +308,13 @@ def test_odysseus_bearer_parser_rejects_other_credentials(value):
assert is_odysseus_bearer_authorization(value) is False assert is_odysseus_bearer_authorization(value) is False
def test_internal_header_match_preserves_an_exact_whitespace_token(monkeypatch):
configured_token = "\t configured token \t"
monkeypatch.setattr(middleware, "INTERNAL_TOOL_TOKEN", configured_token)
assert middleware._internal_header_matches(configured_token) is True
def test_mounted_root_path_gate_precedes_json_validation(monkeypatch): def test_mounted_root_path_gate_precedes_json_validation(monkeypatch):
side_effects: list[str] = [] side_effects: list[str] = []
monkeypatch.setattr(codex_routes, "COOKBOOK_STATE_FILE", _PoisonPath()) monkeypatch.setattr(codex_routes, "COOKBOOK_STATE_FILE", _PoisonPath())