PensionsPortal.ie applies a set of HTTP security headers to every response. These headers are configured in next.config.ts and applied globally via Next.js’s headers() async function.
All headers are applied to all routes (source: "/(.*)") in next.config.ts:
const securityHeaders = [
{ key: "X-DNS-Prefetch-Control", value: "on" },
{ key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" },
{ key: "X-Frame-Options", value: "SAMEORIGIN" },
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
{ key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },
{ key: "Content-Security-Policy", value: "..." },
]
Strict-Transport-Security (HSTS)
max-age=63072000; includeSubDomains; preload
- max-age=63072000 — 2 years (720 days). Browsers will only connect via HTTPS for this duration.
- includeSubDomains — policy applies to all subdomains
- preload — domain is eligible for submission to HSTS preload lists embedded in browsers
Content Security Policy (CSP)
default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline';
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
img-src 'self' blob: data: https:;
font-src 'self' https://fonts.gstatic.com;
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
| Directive | Value | Rationale |
|---|
default-src | 'self' | Default allow-list: same origin only |
script-src | 'self' 'unsafe-eval' 'unsafe-inline' | Required by Next.js runtime; unsafe-eval can be tightened with nonces in future |
style-src | 'self' 'unsafe-inline' fonts.googleapis.com | Tailwind CSS uses inline styles; Google Fonts |
img-src | 'self' blob: data: https: | User-uploaded images and remote HTTPS sources |
font-src | 'self' fonts.gstatic.com | Google Fonts delivery |
object-src | 'none' | Blocks Flash and other plugins entirely |
base-uri | 'self' | Prevents base tag injection attacks |
form-action | 'self' | Forms cannot submit to external domains |
frame-ancestors | 'none' | Equivalent to X-Frame-Options: DENY (stricter than SAMEORIGIN) |
upgrade-insecure-requests | — | Browser upgrades HTTP sub-resources to HTTPS |
unsafe-eval is currently required by the Next.js development runtime. Consider implementing nonce-based CSP in a future iteration to allow removal of unsafe-eval in production.
X-Frame-Options
Prevents the application from being embedded in iframes on external domains, protecting against clickjacking. Note: the CSP frame-ancestors 'none' directive is stricter and takes precedence in modern browsers.
X-Content-Type-Options
Prevents browsers from MIME-type sniffing, which can cause JavaScript execution from non-script resources.
Referrer-Policy
strict-origin-when-cross-origin
Sends the full referrer for same-origin requests; sends only the origin (no path) for cross-origin HTTPS requests; sends nothing for HTTP requests. Prevents leaking URL paths containing IDs to third-party services.
Permissions-Policy
camera=(), microphone=(), geolocation=()
Explicitly disables camera, microphone, and geolocation access. The application does not use these browser APIs.
X-DNS-Prefetch-Control
Allows DNS prefetching for performance. This is a low-risk setting; DNS prefetch does not expose request contents.
The X-Powered-By: Next.js header is explicitly removed to avoid disclosing the framework version to potential attackers.