Skip to content

Conversation

@shoummu1
Copy link
Collaborator

@shoummu1 shoummu1 commented Dec 2, 2025

🐛 Bug-fix PR

📌 Summary

Fixes iframe embedding issue where CSP frame-ancestors directive was always set even when users configured X_FRAME_OPTIONS to allow embedding. PR #1352 fixed the X-Frame-Options header but missed the CSP frame-ancestors directive, which takes precedence in modern browsers.

  • Syncs CSP frame-ancestors with X-Frame-Options configuration
  • Adds support for X_FRAME_OPTIONS=null to completely disable iframe restrictions
  • Includes file: scheme support for X_FRAME_OPTIONS="" to enable testing
  • Updates documentation with comprehensive iframe embedding guidance

🔗 Related Issue

#1327

🐞 Root Cause

  1. PR Fix empty X_FRAME_OPTIONS override #1352 fixed X-Frame-Options header handling but not the CSP frame-ancestors directive
  2. CSP frame-ancestors was always being added to responses based on X_FRAME_OPTIONS value
  3. No way to completely remove frame-ancestors directive (even X_FRAME_OPTIONS="" added frame-ancestors *)
  4. Modern browsers prioritize CSP over legacy X-Frame-Options, causing iframe blocking
  5. Wildcard * in CSP doesn't include file:// scheme, breaking local testing

🧪 Verification

Check Command Status
Manual curl test - null X_FRAME_OPTIONS=null → curl shows NO frame-ancestors ✅ pass
Manual curl test - empty X_FRAME_OPTIONS="" → curl shows frame-ancestors * file: http: https: ✅ pass
Manual curl test - DENY X_FRAME_OPTIONS=DENY → curl shows frame-ancestors 'none' ✅ pass
Browser iframe test Tested MCP Gateway Admin UI embedded in external HTML page with null/empty → No CSP errors ✅ pass
Browser iframe test Tested MCP Gateway Admin UI embedded in external HTML page with DENY → CSP violation error ✅ pass
Config validator test Settings with "null"/"none" string → converts to Python None ✅ pass

✅Testing Checklist

  • Tested with real MCP Gateway Admin UI in iframe
  • Verified headers with curl for all configurations
  • Confirmed browser console shows/hides CSP errors appropriately
  • Validated both legacy and modern browser behavior
image

📐 MCP Compliance

  • ✅ No breaking change to MCP protocol or clients
  • ✅ Maintains existing security defaults (X_FRAME_OPTIONS=DENY)
  • ✅ Backward compatible with all existing configurations
  • ✅ Optional feature - users must explicitly set null or "" to enable embedding

📄 Files Changed

  • mcpgateway/config.py - Added validator to normalize "null"/"none" strings
  • mcpgateway/middleware/security_headers.py - Conditional CSP frame-ancestors logic
  • README.md - Updated iframe embedding documentation
  • .env.example - Comprehensive X_FRAME_OPTIONS comments

💡 Configuration Options After Fix

X_FRAME_OPTIONS X-Frame-Options Header CSP frame-ancestors Use Case
DENY (default) DENY 'none' Block all iframe embedding (recommended)
SAMEORIGIN SAMEORIGIN 'self' Allow same-domain embedding only
"" (empty) Not set * file: http: https: Allow all sources including file://
null or none Not set Not added Completely unrestricted (no headers)

@shoummu1 shoummu1 requested a review from kevalmahajan December 2, 2025 12:06
@shoummu1 shoummu1 assigned madhav165 and unassigned madhav165 Dec 2, 2025
@shoummu1 shoummu1 requested a review from madhav165 December 2, 2025 12:06
@shoummu1 shoummu1 marked this pull request as ready for review December 2, 2025 12:06
Copy link
Member

@kevalmahajan kevalmahajan left a comment

Choose a reason for hiding this comment

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

Works as expected.

@kevalmahajan kevalmahajan merged commit d0edab6 into main Dec 2, 2025
45 checks passed
@kevalmahajan kevalmahajan deleted the fix-xframe-issue branch December 2, 2025 16:09
@kevalmahajan kevalmahajan mentioned this pull request Dec 4, 2025
4 tasks
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.

4 participants