Security Headers: HSTS, X-Frame-Options, X-Content-Type-Options & More
Security Headers: HSTS, X-Frame-Options, X-Content-Type-Options & More
Release: v1.0.24 · Control: SEC-12 · Category: Infrastructure Security
As of v1.0.24, Calmony Pay sets a standard suite of HTTP security response headers on every API response. These headers form a browser-level defence-in-depth layer that is independent of application logic — they are enforced by the HTTP client (browser or API consumer) before any content is parsed or rendered.
Why This Matters for a Payment API
Payment processing surfaces are high-value targets. Even when application code is correct, the absence of transport and content-security headers can expose end users and integrators to:
- Downgrade attacks — an attacker on the network intercepts an HTTP redirect and strips TLS before the user's browser upgrades to HTTPS.
- Clickjacking — a malicious site frames a payment confirmation page inside an invisible
<iframe>, tricking users into authorising transactions. - MIME confusion attacks — a browser re-interprets a JSON response as executable HTML/JavaScript if the
Content-Typeis not locked down. - Referrer leakage — sensitive URL fragments (e.g. session tokens in query strings) are forwarded in the
Refererheader to third-party analytics or CDN origins.
Headers Configured
Strict-Transport-Security
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
max-age=63072000— browsers must use HTTPS for this domain for the next two years.includeSubDomains— the policy applies to every subdomain (e.g.api.calmonypay.com,sandbox.calmonypay.com).preload— the domain is eligible for inclusion in browser HSTS preload lists (Chrome, Firefox, Safari, Edge), meaning HTTPS is enforced even on a user's very first visit before any HTTP exchange has occurred.
This is the single most impactful header for a payment API. Without it a man-in-the-middle attacker can silently strip TLS.
X-Frame-Options
X-Frame-Options: DENY
Prevents any page served by Calmony Pay from being embedded inside an <iframe>, <frame>, <embed>, or <object> element — on any origin, including Calmony's own. This eliminates the clickjacking attack surface entirely.
X-Content-Type-Options
X-Content-Type-Options: nosniff
Instructs the browser not to override the server-declared Content-Type. Without this, some browsers will attempt to "sniff" the actual content type of a response, which can cause a JSON blob to be interpreted and executed as HTML if it contains script-like content.
Referrer-Policy
Referrer-Policy: strict-origin-when-cross-origin
| Request type | Referer value sent |
|---|---|
| Same-origin, HTTPS | Full URL |
| Cross-origin, HTTPS → HTTPS | Origin only (e.g. https://calmonypay.com) |
| Any, HTTPS → HTTP | Nothing |
This prevents full URLs — which may include API keys, session identifiers, or invoice IDs in query parameters — from leaking to third-party origins.
Permissions-Policy
Permissions-Policy: camera=(), microphone=(), geolocation=()
Explicitly revokes browser permission to access the camera, microphone, and geolocation APIs for all browsing contexts served by this origin. Calmony Pay has no legitimate use for these APIs; restricting them reduces the blast radius of any future XSS or supply-chain vulnerability.
Configuration
All headers are applied globally via the headers() array in next.config.ts. No application-level code changes are required. The headers are returned on every response regardless of route or HTTP method.
// next.config.ts (simplified)
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=()',
},
],
},
];
}
Verifying the Headers
You can verify the headers are present on any response using curl:
curl -I https://api.calmonypay.com/v1/health
Expected output (relevant headers):
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=()
Alternatively, use securityheaders.com to get a graded report against your deployed domain.
Related Controls
| Control | Description |
|---|---|
| SEC-12 | Security response headers (this release) |