Skip to content

feat(security): add anti-framing headers (X-Frame-Options + CSP frame-ancestors)#430

Merged
wyuc merged 1 commit intoTHU-MAIC:mainfrom
YizukiAme:fix/add-frame-ancestors
Apr 15, 2026
Merged

feat(security): add anti-framing headers (X-Frame-Options + CSP frame-ancestors)#430
wyuc merged 1 commit intoTHU-MAIC:mainfrom
YizukiAme:fix/add-frame-ancestors

Conversation

@YizukiAme
Copy link
Copy Markdown
Contributor

@YizukiAme YizukiAme commented Apr 14, 2026

Summary

Add X-Frame-Options: SAMEORIGIN and Content-Security-Policy: frame-ancestors 'self' response headers to prevent clickjacking and unauthorized third-party embedding of the application.

Supports an optional ALLOWED_FRAME_ANCESTORS environment variable to whitelist trusted origins (e.g., for partner sites that need to embed OpenMAIC).

Changes

next.config.ts

  • Added headers() function that applies anti-framing headers to all routes via the /(.*) source pattern.
  • X-Frame-Options: SAMEORIGIN — legacy header for older browser compatibility (omitted when custom ancestors are configured, since X-Frame-Options doesn't support allow-lists).
  • Content-Security-Policy: frame-ancestors 'self' — modern standard that restricts which origins can embed this site in an iframe.
  • Reads optional ALLOWED_FRAME_ANCESTORS env var to append trusted origins (space-separated).

tests/server/security-headers.test.ts (new)

  • Verifies that headers() is defined in the Next.js config.
  • Asserts both X-Frame-Options and Content-Security-Policy: frame-ancestors are present with default config.
  • Tests that ALLOWED_FRAME_ANCESTORS correctly appends origins to the CSP directive.
  • Tests that X-Frame-Options is omitted when custom ancestors are set.
  • Tests multiple space-separated origins.

Configuration

By default, only same-origin framing is allowed. To whitelist additional origins:

# .env or Vercel environment variables
ALLOWED_FRAME_ANCESTORS=https://partner.example.com https://another.example.com

Verification

# All 100 tests pass, zero regressions
npx vitest run
# Test Files  8 passed (8)
#      Tests  100 passed (100)

After deployment, the headers can be verified with:

curl -sI https://open.maic.chat/ | grep -iE "x-frame|content-security"
# Expected:
# X-Frame-Options: SAMEORIGIN
# Content-Security-Policy: frame-ancestors 'self'

Closes #428
Closes #429

@YizukiAme YizukiAme force-pushed the fix/add-frame-ancestors branch 3 times, most recently from a9a4313 to 99d8478 Compare April 14, 2026 13:02
…-ancestors)

Add X-Frame-Options: SAMEORIGIN and Content-Security-Policy: frame-ancestors 'self'
response headers to prevent clickjacking and unauthorized third-party embedding.

Closes THU-MAIC#428
@YizukiAme YizukiAme force-pushed the fix/add-frame-ancestors branch from 99d8478 to 03783b9 Compare April 14, 2026 13:56
Copy link
Copy Markdown
Contributor

@wyuc wyuc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@wyuc wyuc merged commit ca550aa into THU-MAIC:main Apr 15, 2026
2 checks passed
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.

Third-party site embedding OpenMAIC with conflicting IP claims Missing anti-framing headers on open.maic.chat

2 participants