[Bug]:iFrame context-forge giving error "ancestor violates Content Security Policy directive"
🐞 Bug Summary
We are trying to iFrame the mcp context forge into another web portal. But we are getting error in the UI "Refused to frame 'https://dev.mcp-gateway.com:4444/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'none'"."
We used default docker-compose to bringup the application and added the below 2 additional ENV variables.
X_FRAME_OPTIONS="" ALLOWED_ORIGINS=["*"]
Seems like the mcp-context-forge backend code is overriding this options which we are passing.
Could you please guide how to resolve this.
🧩 Affected Component
Select the area of the project impacted:
- [ ]
mcpgateway- API - [ ]
mcpgateway- UI (admin panel) - [ ]
mcpgateway.wrapper- stdio wrapper - [ ] Federation or Transports
- [ ] CLI, Makefiles, or shell scripts
- [ ] Container setup (Docker/Podman/Compose)
- [ ] Other (explain below)
🔁 Steps to Reproduce
- ...
- ...
- ...
🤔 Expected Behavior
What should have happened instead?
📓 Logs / Error Output
Paste any relevant stack traces or logs here. ⚠️ Do not paste secrets, credentials, or tokens.
🧠 Environment Info
You can retrieve most of this from the /version endpoint.
| Key | Value |
|---|---|
| Version or commit | e.g. v0.9.0 or main@a1b2c3d |
| Runtime | e.g. Python 3.11, Gunicorn |
| Platform / OS | e.g. Ubuntu 22.04, macOS |
| Container | e.g. Docker, Podman, none |
🧩 Additional Context (optional)
Add any configuration details, flags, or related issues.
@sunvk the problem is that X_FRAME_OPTIONS=* is not a valid value. The security middleware first validates the X_FRAME_OPTIONS value. When it sees an invalid value like *, it ignores it and uses the default DENY setting, which translates to CSP frame-ancestors 'none'.
Below are the valid X_FRAME_OPTIONS values:
-
DENY— Block all iframe embedding (default) -
SAMEORIGIN— Allow embedding from same domain only -
ALLOW-FROM https://domain.com— Allow embedding from specific domain -
""(empty string) — Remove restriction entirely
Here are some ways to fix this in your docker-compose:
Option 1: Allow Same-Origin
environment:
- X_FRAME_OPTIONS=SAMEORIGIN
- ALLOWED_ORIGINS=["*"]
Option 2: Allow All Origins
environment:
- X_FRAME_OPTIONS=""
- ALLOWED_ORIGINS=["*"]
Option 3: Allow Specific Domain
environment:
- X_FRAME_OPTIONS=ALLOW-FROM https://your-portal-domain.com
- ALLOWED_ORIGINS=["*"]
Hello @shoummu1 @crivetimihai We tried all the 3 options you mentioned above in docker compose.yaml Still getting "Refused to frame 'https://mcp-gateway.com:4444/' because an ancestor violates the following Content Security Policy directive"
ENV Section from Docker Compose.yaml
environment: - HOST=0.0.0.0 - PORT=4444 - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD:-mysecretpassword}@postgres:5432/mcp # - DATABASE_URL=mysql+pymysql://mysql:${MYSQL_PASSWORD:-changeme}@mariadb:3306/mcp # - DATABASE_URL=mysql+pymysql://admin:${MARIADB_PASSWORD:-changeme}@mariadb:3306/mcp # - DATABASE_URL=mongodb://admin:${MONGO_PASSWORD:-changeme}@mongodb:27017/mcp - CACHE_TYPE=redis # backend for caching (memory, redis, database, or none) - REDIS_URL=redis://redis:6379/0 # JWT Configuration - Choose ONE approach: # Option 1: HMAC (Default - Simple deployments) - JWT_ALGORITHM=HS256 - JWT_SECRET_KEY=my-test-key # Option 2: RSA (Production - Asymmetric, uncomment and generate certs) # - JWT_ALGORITHM=RS256 # - JWT_PUBLIC_KEY_PATH=/app/certs/jwt/public.pem # - JWT_PRIVATE_KEY_PATH=/app/certs/jwt/private.pem - JWT_AUDIENCE=mcpgateway-api - JWT_ISSUER=mcpgateway - EMAIL_AUTH_ENABLED=true - [email protected] - PLATFORM_ADMIN_PASSWORD=admin123 - REQUIRE_TOKEN_EXPIRATION=false - MCPGATEWAY_UI_ENABLED=true - MCPGATEWAY_ADMIN_API_ENABLED=true # Security configuration (using defaults) - ENVIRONMENT=development - SECURITY_HEADERS_ENABLED=true - CORS_ALLOW_CREDENTIALS=true - SECURE_COOKIES=false # - SSL=true # - CERT_FILE=/app/certs/cert.pem # - KEY_FILE=/app/certs/key.pem # Uncomment to enable plugins - PLUGINS_ENABLED=true # Uncomment to enable catalog - MCPGATEWAY_CATALOG_ENABLED=true - MCPGATEWAY_CATALOG_FILE=/app/mcp-catalog.yml # Authentication configuration - AUTH_REQUIRED=true - MCP_CLIENT_AUTH_ENABLED=true - TRUST_PROXY_AUTH=false # Logging configuration - LOG_LEVEL=ERROR # Default to ERROR for production performance - DISABLE_ACCESS_LOG=true # Disable uvicorn access logs for performance (massive I/O overhead) - TLS_INSECURE=true - SSL_INSECURE=true #- X_FRAME_OPTIONS=ALLOW-FROM https://vsop.verizon.com/ # - X_FRAME_OPTIONS=SAMEORIGIN - X_FRAME_OPTIONS="" - ALLOWED_ORIGINS=["*"]
@sunvk I ran a quick test with the above config on my end and noticed that X-Frame-Options: DENY is still being sent even though X_FRAME_OPTIONS="". I'm preparing a PR that will change the hardcoded default from DENY to SAMEORIGIN in the source code.
Hello @shoummu1 If you change it from DENY to SAMEORIGIN, still we will get error if I pass the value X_FRAME_OPTIONS="" right? What if both domains are differant?
@sunvk Yes, that's right. Changing from DENY to SAMEORIGIN won't solve the core issue if both domains are different. I'm working on a fix that changes the middleware logic to properly distinguish between "no value set" versus "empty string explicitly set". This will allow you to completely disable the X-Frame-Options header by setting X_FRAME_OPTIONS="" in your Docker environment, which will enable iframe embedding from any origin.
Please see #1352
@sunvk we have addressed this in the upcoming 0.9.0 with PR #1352 - please re-open if there are issues.
@crivetimihai @shoummu1
I am getting same error with latest version as well.
Framing 'https://dev-vsop.verizon.com:4444/' violates the following Content Security Policy directive: "frame-ancestors 'none'". The request has been blocked. Understand this error
My Docker-compose.yml has below env vars.
- X_FRAME_OPTIONS=""
- ALLOWED_ORIGINS=["*"]
Reopening based on input from @sunishvkvz