open-notebook/api
Pico fd7dee7ced
fix: don't combine wildcard CORS origins with allow_credentials (#1013)
* fix: don't combine wildcard CORS origins with allow_credentials

Combining allow_origins=["*"] with allow_credentials=True makes
Starlette's CORSMiddleware reflect the request's Origin header verbatim
instead of returning a literal "*" (browsers reject a literal wildcard
alongside credentials) - defeating the origin allowlist for any
credentialed request.

allow_credentials is now tied to whether CORS_ORIGINS was explicitly
scoped: False for the default wildcard, True once an operator opts into
specific origins. _cors_headers() (the manual CORS builder for error
responses raised before CORSMiddleware runs) is updated to match, so it
can't grant credentials the real middleware wouldn't.

Not independently exploitable today (the frontend never sends
credentialed requests, and auth is a Bearer header, not a cookie), but
there's no reason to allow it for the default wildcard case.

* fix: key allow_credentials on the parsed origins list, not the env var

An operator who explicitly sets CORS_ORIGINS=* got allow_credentials=True
with a wildcard origin list - the exact reflect-any-Origin behavior this
change exists to prevent. Introduce CORS_ALLOW_CREDENTIALS keyed on the
parsed list containing '*' and use it at both the middleware registration
and the manual error-response headers; replace the tautological formula
tests with ones exercising the real parser.

---------

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-07-10 11:10:41 -03:00
..
routers fix: make validate_url() async so DNS resolution doesn't block the event loop (#1011) 2026-07-10 10:43:36 -03:00
__init__.py Api podcast migration (#93) 2025-07-17 08:36:11 -03:00
auth.py fix: use constant-time comparison for the API password (#1003) 2026-07-10 10:27:16 -03:00
chat_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
CLAUDE.md fix: don't combine wildcard CORS origins with allow_credentials (#1013) 2026-07-10 11:10:41 -03:00
client.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
command_service.py Version 1 (#160) 2025-10-18 12:46:22 -03:00
context_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
credentials_service.py fix: don't leak filesystem info via Vertex credential test errors (#1012) 2026-07-10 11:07:04 -03:00
embedding_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
episode_profiles_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
insights_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
main.py fix: don't combine wildcard CORS origins with allow_credentials (#1013) 2026-07-10 11:10:41 -03:00
models.py feat: Recently Viewed section for notebooks and sources (#979) 2026-07-03 12:39:14 -03:00
models_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
notebook_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
notes_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
podcast_api_service.py Version 1 (#160) 2025-10-18 12:46:22 -03:00
podcast_service.py refactor: reorganize folder structure for better maintainability 2026-01-03 14:04:27 -03:00
search_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
settings_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
sources_service.py Feat/localization tests docker (#371) 2026-01-15 13:51:05 -03:00
transformations_service.py feat: per-transformation custom model selection (#978) 2026-07-03 12:30:50 -03:00