Skip to content

Harden browser auth and related trust boundaries#51

Draft
toimfortes wants to merge 8 commits intobcurts:mainfrom
toimfortes:hardening/upstream-slices
Draft

Harden browser auth and related trust boundaries#51
toimfortes wants to merge 8 commits intobcurts:mainfrom
toimfortes:hardening/upstream-slices

Conversation

@toimfortes
Copy link
Copy Markdown

Summary

This PR applies a focused hardening pass to a few trust-boundary issues in agentchattr:

  • move browser auth from a page-exposed session token to an HttpOnly session cookie plus CSRF token
  • close an accidental public write gap on POST /api/roles/{agent}
  • require cookie auth for WebSockets and enforce same-origin checks there too
  • restrict /api/open-path to known local roots instead of arbitrary filesystem paths
  • reject SVG uploads and SVG attachments in MCP chat tools while custom SVG hats remain unsafe
  • fix archive import persistence so archive round-trips work again
  • warn explicitly when API agents forward room context to non-local endpoints

Why

The core issue was trust-boundary collapse:

  • agent-controlled SVG could be persisted and injected into the UI
  • the browser held a powerful bearer token in page-accessible JavaScript
  • one write endpoint under /api/roles was unintentionally public because of prefix-based auth bypass

That combination made XSS and local privilege escalation risks much worse than they needed to be.

Validation

Ran successfully:

  • pytest -q
  • python -m py_compile app.py run.py archive.py mcp_bridge.py wrapper_api.py tests/test_security_middleware.py tests/test_archive_feature.py
  • node --check static/chat.js

Notes

I kept the changes intentionally narrow and split into small commits:

  1. browser auth + CSRF hardening
  2. archive import persistence fix
  3. SVG rejection in MCP attachment paths
  4. remote API endpoint warning
  5. rationale / hardening docs

The docs are included because these changes affect core security assumptions, not just local deployment preferences.

@toimfortes
Copy link
Copy Markdown
Author

Suggested review order for this PR:

  1. 29db088 Harden browser auth with cookies and CSRF
  2. cf89fae Fix archive import persistence path
  3. 46adff0 Reject SVG attachments in MCP chat tools
  4. eda448f Warn when API agents target remote endpoints
  5. dcbf463 Document security hardening plan and rationale

Validation run on the branch:

  • pytest -q
  • python -m py_compile app.py run.py archive.py mcp_bridge.py wrapper_api.py tests/test_security_middleware.py tests/test_archive_feature.py
  • node --check static/chat.js

The first commit is the main security boundary change. The rest are narrower follow-up fixes/documentation.

@toimfortes
Copy link
Copy Markdown
Author

Second hardening pass added two more focused commits:

  • 19a23ea Tighten browser request filtering and upload headers

    • blocks cross-site browser requests when Sec-Fetch-Site is present and not same-origin/none
    • serves uploaded files with X-Content-Type-Options: nosniff
  • 2f6aee3 Require explicit opt-in for remote API agents

    • requires allow_remote = true for non-local API endpoints
    • updates config/examples/README to make the exfiltration boundary explicit
    • adds unit coverage for the endpoint policy helper

Branch validation still passes:

  • pytest -q
  • python -m py_compile app.py run.py archive.py mcp_bridge.py wrapper_api.py tests/test_security_middleware.py tests/test_archive_feature.py tests/test_wrapper_api.py
  • node --check static/chat.js

@toimfortes
Copy link
Copy Markdown
Author

Third pass added one more hardening commit:

  • 843187c Make public route policy explicit and align disabled SVG UX
    • factors public browser route policy into an explicit helper
    • adds regression coverage that mutating routes do not succeed without auth
    • applies a small set of response security headers globally
    • removes misleading /hatmaking and /artchallenge SVG UX now that SVG hats/uploads are disabled

Validation still passes:

  • pytest -q
  • python -m py_compile app.py wrapper_api.py tests/test_security_middleware.py tests/test_wrapper_api.py tests/test_archive_feature.py
  • node --check static/chat.js

@bcurts
Copy link
Copy Markdown
Owner

bcurts commented Apr 18, 2026

Hi, this is still marked as a work in progress, so it can't be merged, are you ready to submit it yet?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants