HTTP Security·Headers·Web Transport

MCP server HTTP security headers: CSP, HSTS, CORP, COEP, and the full checklist

HTTP security headers are a lightweight but high-value defense layer for MCP servers with HTTP interfaces. They don't protect the API itself — they protect against browser-based attacks on the admin dashboard, credential management pages, and any browser-rendered interface that interacts with your MCP server. Getting them right takes 30 minutes and prevents XSS, clickjacking, cross-origin data leaks, and timing-based Spectre attacks.

Why security headers matter for MCP servers

Many developers think security headers are only relevant for traditional web apps. MCP servers with HTTP interfaces typically have at least: an admin dashboard for managing tools and credentials, an API key management page, a health check endpoint, and sometimes a tool execution log viewer. All of these are browser-rendered interfaces that are vulnerable to the same attacks headers protect against.

Additionally, the MCP API endpoints themselves benefit from headers: a CORS policy on API endpoints prevents cross-origin JavaScript from making authenticated calls to your MCP API from a page the user visits on a different domain.

Content-Security-Policy (CSP) for MCP admin interfaces

CSP restricts which scripts, styles, images, and connections a page can load. For MCP server admin interfaces, a restrictive CSP prevents XSS payloads from executing even if an attacker injects a script tag via a stored XSS in tool logs or audit records. A minimal baseline CSP for an admin interface that loads its own scripts:

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'

Key directives: frame-ancestors 'none' prevents clickjacking (replaces X-Frame-Options). base-uri 'self' prevents base tag injection. form-action 'self' prevents form submission hijacking. Avoid 'unsafe-eval' and 'unsafe-inline' in script-src — if your frontend requires eval, refactor it.

For MCP API endpoints (not browser-rendered): Content-Security-Policy: default-src 'none' — API responses shouldn't render anything, so a deny-all CSP is appropriate.

Strict-Transport-Security (HSTS)

HSTS tells browsers to only connect via HTTPS for a specified duration. Without it, a network attacker can perform an HTTP downgrade on the first request. For MCP servers:

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

Two years max-age. includeSubDomains covers all subdomains (important if your MCP server uses api.yourdomain.com and your admin panel uses admin.yourdomain.com). Submit to the HSTS preload list for maximum protection — preloaded domains are hardcoded into browsers as HTTPS-only, so there's no first-request downgrade window at all.

Cross-Origin Resource Policy (CORP) and Cross-Origin Embedder Policy (COEP)

CORP prevents other origins from loading your MCP server's resources. This matters for API endpoints: without CORP, a page on another origin can use an image tag or script tag to make a credentialed request to your API and infer response data from timing or error states (Spectre-based cross-origin reads). Set: Cross-Origin-Resource-Policy: same-origin on all API endpoints.

COEP (Cross-Origin-Embedder-Policy: require-corp) combined with COOP (Cross-Origin-Opener-Policy: same-origin) enables the browser's SharedArrayBuffer isolation mode, which prevents Spectre attacks on sensitive data loaded in the same browsing context. This is especially relevant for MCP admin interfaces that display sensitive tool results in the browser.

Permissions-Policy: lock down browser features

Permissions-Policy (formerly Feature-Policy) restricts which browser APIs the page can use. For an MCP admin interface that doesn't need camera, microphone, geolocation, or payment APIs:

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), bluetooth=()

If a stored XSS payload fires, it can't exfiltrate audio via microphone or location via geolocation — the browser will block it at the feature policy level.

X-Content-Type-Options and Referrer-Policy

X-Content-Type-Options: nosniff prevents MIME-type sniffing — a browser that receives a response with Content-Type: text/plain won't execute it as JavaScript even if it looks like JS. Referrer-Policy: strict-origin-when-cross-origin prevents your MCP server's URL (which might contain session identifiers or tool IDs) from leaking in the Referer header when a user clicks a link to an external site from an admin page.

CORS configuration for MCP API endpoints

CORS is not a security header you add to prevent attacks — it's a security mechanism that restricts which origins can make cross-origin requests to your API. For MCP APIs: set Access-Control-Allow-Origin to the specific origins that need access (your admin dashboard domain, your CLI tool's local server), never *. Set Access-Control-Allow-Credentials: true only if your API uses cookies (most MCP APIs use Bearer tokens, so credentials: true is unnecessary and harmful).

What SkillAudit checks for security headers

SkillAudit's Documentation Completeness and Security axes both cover header analysis. For MCP server GitHub repositories, the static analyzer checks:

Check your MCP server's security headers → SkillAudit scans your server configuration for missing or misconfigured HTTP security headers