HERMES-GIELIE/tests
nesquena-hermes f948baceb6
fix: CSRF check fails behind reverse proxy on non-standard ports (#360)
* fix: CSRF check fails behind reverse proxy on non-standard ports

When serving behind a reverse proxy (e.g. Nginx Proxy Manager) on a
non-standard port like 8000, the browser sends
`Origin: https://example.com:8000` but the proxy forwards `Host: example.com`
(without the port). The existing CSRF check compared these as raw strings,
causing all POST requests to be rejected with 403.

This commit:
- Adds `_normalize_host_port()` to properly parse host:port pairs (incl. IPv6)
- Adds `_ports_match()` that treats absent port as equivalent to 80/443
- Adds `HERMES_WEBUI_ALLOWED_ORIGINS` env var for explicitly trusting origins
  when port normalization alone isn't sufficient (e.g. port 8000)
- Adds unit tests covering port normalization, allowlist, and rejection cases

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: CSRF port normalization — scheme-aware, allowlist validation, 29 tests (#360)

api/routes.py:
- _normalize_host_port(): parse host:port including IPv6 bracket notation
- _ports_match(scheme, origin_port, allowed_port): scheme-aware — http absent=:80,
  https absent=:443; prevents cross-protocol false match (http://host:80 no
  longer passes for https://host:443 server)
- _allowed_public_origins(): parse HERMES_WEBUI_ALLOWED_ORIGINS env var;
  warn and skip entries missing scheme prefix
- _check_csrf(): extract origin scheme, pass to _ports_match; add origin_scheme

tests/test_sprint29.py: 29 new tests (5 from PR + 24 added in review)
- Unit tests for _normalize_host_port and _ports_match helpers
- Cross-protocol rejection (http vs https default ports)
- Explicit :80 / :443 same-origin pass
- Non-default port rejection
- Bug scenario with/without allowlist
- Comma-separated allowlist
- No-scheme allowlist warning
- Trailing-slash normalization

CHANGELOG.md: v0.50.16 entry; 900 tests total (up from 871)

---------

Co-authored-by: liangxu.5 <liangxu.5@bytedance.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
2026-04-13 12:23:16 -07:00
..
__init__.py Hermes WebUI v0.1.0 — initial public release 2026-03-30 20:40:19 -07:00
conftest.py feat: composer-centric UI refresh + Hermes Control Center (v0.50.0, closes #242) 2026-04-12 11:55:40 -07:00
test_approval_unblock.py fix: unskip 16 approval tests — remove stale has_pending/pop_pending imports 2026-04-10 10:10:28 -07:00
test_auth_sessions.py fix(auth): prune expired sessions on every verify to prevent memory leak (#196) 2026-04-09 18:05:23 -07:00
test_cancel_interrupt.py v0.46.0: security, Docker UID/GID, model discovery, i18n, cancel fix 2026-04-11 10:17:52 -07:00
test_gateway_sync.py feat: real-time gateway session sync (Phase 1) (#274) 2026-04-11 20:53:12 -07:00
test_issue341.py fix: add table styles to .msg-body for readable bordered chat tables (fixes #341) (#345) 2026-04-13 00:08:30 -07:00
test_issue342.py feat: autolink plain URLs in chat messages (fixes #342) (#346) 2026-04-13 00:05:04 -07:00
test_issue347.py feat: KaTeX math rendering for LaTeX in chat + workspace previews (#352) 2026-04-13 11:40:15 -07:00
test_mobile_layout.py fix: mobile Enter inserts newline (closes #269) (#320) 2026-04-12 12:41:12 -07:00
test_model_resolver.py v0.47.0: dialogs, session menu, /skills, mobile fixes, mobile QA suite 2026-04-11 12:19:12 -07:00
test_onboarding_mvp.py feat(onboarding): add one-shot bootstrap and first-run setup wizard (#285) 2026-04-12 00:11:41 -07:00
test_onboarding_static.py feat(onboarding): add one-shot bootstrap and first-run setup wizard (#285) 2026-04-12 00:11:41 -07:00
test_profile_env_isolation.py fix: isolate profile .env secrets on switch (#351) 2026-04-13 00:51:55 -07:00
test_provider_mismatch.py fix: warn on provider/model mismatch, surface auth errors (#266) 2026-04-11 21:25:18 -07:00
test_regressions.py feat: composer-centric UI refresh + Hermes Control Center (v0.50.0, closes #242) 2026-04-12 11:55:40 -07:00
test_security_redaction.py v0.46.0: security, Docker UID/GID, model discovery, i18n, cancel fix 2026-04-11 10:17:52 -07:00
test_spanish_locale.py feat(i18n): add Spanish locale for WebUI (#275) 2026-04-11 20:06:37 -07:00
test_sprint1.py Hermes Web UI — Sprints 11-14: multi-provider models, settings, session QoL, alerts, polish 2026-03-31 07:02:47 +00:00
test_sprint2.py Hermes WebUI v0.1.0 — initial public release 2026-03-30 20:40:19 -07:00
test_sprint3.py Hermes WebUI v0.1.0 — initial public release 2026-03-30 20:40:19 -07:00
test_sprint4.py Hermes WebUI v0.1.0 — initial public release 2026-03-30 20:40:19 -07:00
test_sprint5.py Hermes WebUI v0.1.0 — initial public release 2026-03-30 20:40:19 -07:00
test_sprint6.py feat: composer-centric UI refresh + Hermes Control Center (v0.50.0, closes #242) 2026-04-12 11:55:40 -07:00
test_sprint7.py Hermes WebUI v0.1.0 — initial public release 2026-03-30 20:40:19 -07:00
test_sprint8.py Hermes WebUI v0.1.0 — initial public release 2026-03-30 20:40:19 -07:00
test_sprint9.py Hermes WebUI v0.1.0 — initial public release 2026-03-30 20:40:19 -07:00
test_sprint10.py Hermes WebUI v0.1.0 — initial public release 2026-03-30 20:40:19 -07:00
test_sprint11.py Hermes Web UI — Sprints 11-14: multi-provider models, settings, session QoL, alerts, polish 2026-03-31 07:02:47 +00:00
test_sprint12.py Hermes Web UI — Sprints 11-14: multi-provider models, settings, session QoL, alerts, polish 2026-03-31 07:02:47 +00:00
test_sprint13.py Hermes Web UI — Sprints 11-14: multi-provider models, settings, session QoL, alerts, polish 2026-03-31 07:02:47 +00:00
test_sprint14.py Hermes Web UI — Sprints 11-14: multi-provider models, settings, session QoL, alerts, polish 2026-03-31 07:02:47 +00:00
test_sprint15.py feat: Sprint 15 — session projects, code copy button, tool card toggle 2026-04-02 00:11:49 -07:00
test_sprint16.py feat: composer-centric UI refresh + Hermes Control Center (v0.50.0, closes #242) 2026-04-12 11:55:40 -07:00
test_sprint17.py feat: Sprint 17 -- workspace breadcrumbs, slash commands, send key setting 2026-04-03 04:13:38 -07:00
test_sprint19.py fix(auth): harden password_hash handling in settings API 2026-04-03 06:21:04 -07:00
test_sprint20.py feat: pluggable i18n with English/Chinese language switcher in Settings 2026-04-08 18:57:50 -07:00
test_sprint20b.py feat: composer-centric UI refresh + Hermes Control Center (v0.50.0, closes #242) 2026-04-12 11:55:40 -07:00
test_sprint23.py fix: test hardening for sprint 23 — handle missing cron/skills modules in test env 2026-04-03 19:16:17 -07:00
test_sprint26.py fix: settings unsaved-changes guard, add Slate theme, improve Light theme 2026-04-05 04:00:24 +00:00
test_sprint27.py fix: harden bot_name — crash guard, XSS escape, sanitization, tests 2026-04-06 15:06:16 +00:00
test_sprint28.py fix: personalities from config.yaml + ephemeral_system_prompt (#139) (#148) 2026-04-06 14:10:30 -07:00
test_sprint29.py fix: CSRF check fails behind reverse proxy on non-standard ports (#360) 2026-04-13 12:23:16 -07:00
test_sprint30.py v0.44.0: approval fix, login CSP, update diagnostics, Lucide icons 2026-04-10 10:02:28 -07:00
test_sprint31.py feat: custom endpoint fields in new profile form (fixes #170, closes #214) 2026-04-10 11:43:49 -07:00
test_sprint32.py feat: auto-install missing agent deps on startup (#215) 2026-04-10 00:42:02 -07:00
test_sprint33.py v0.47.0: dialogs, session menu, /skills, mobile fixes, mobile QA suite 2026-04-11 12:19:12 -07:00
test_sprint34.py fix: use pathlib in test_sprint34 static file opens (no bare relative paths) (#349) 2026-04-13 00:22:58 -07:00
test_sprint35.py fix+feat: session title guard + breadcrumb nav + wider panel + responsive msgs (closes #300, #292) 2026-04-12 10:51:48 -07:00
test_sprint36.py fix: cancel cleanup no longer depends on SSE event (closes #299) 2026-04-12 11:08:59 -07:00
test_sprint37.py feat: workspace panel state persists across refreshes (#321) 2026-04-12 12:50:32 -07:00
test_sprint38.py fix: strip think tags when model emits leading whitespace before <think> (#327) 2026-04-12 14:07:00 -07:00
test_sprint39.py feat: HERMES_WEBUI_SKIP_ONBOARDING env var + synchronous key reload (#330) 2026-04-12 14:26:00 -07:00
test_sprint40.py feat: OAuth provider onboarding path — Codex/Copilot no longer blocks setup (#331) 2026-04-12 14:28:16 -07:00
test_sprint41.py fix: title auto-generation + mobile close button (PR #333) + v0.50.10 2026-04-12 21:45:25 -07:00
test_sprint42.py fix: inject SessionDB into AIAgent for WebUI sessions — enables session_search (#356) 2026-04-13 10:53:58 -07:00
test_sprint43.py security: bandit fixes B310/B324/B110 + QuietHTTPServer (#354) 2026-04-13 11:11:56 -07:00
test_tls_support.py feat: optional HTTPS/TLS support via cert and key env vars (#199) 2026-04-09 18:08:29 -07:00
test_update_checker.py v0.44.0: approval fix, login CSP, update diagnostics, Lucide icons 2026-04-10 10:02:28 -07:00
test_updates.py fix: improve self-update git pull diagnostics (#287) 2026-04-12 00:19:33 -07:00