Skip to content

๐Ÿ›ก๏ธ CORS and Security Headers

To a Programmer, the browser is an untrusted environment. Security headers and Cross-Origin Resource Sharing (CORS) policies are the instructions we give to the browser to enforce our security model on the client side. These are the primary tools used to neutralize entire classes of web vulnerabilities before they can execute.


A Programmer knows that server-side security is only half the battle; you must also harden the โ€œexecution environmentโ€ (the browser).

  • Explicit Deny by Default: We assume that if a security header is missing, the browser is vulnerable.
  • The โ€œSame-Originโ€ Fortress: We treat the Same-Origin Policy (SOP) as a sacred boundary and only puncture it with CORS when absolutely necessary and with extreme precision.
  • Reducing the Attack Surface: We use headers to disable browser features that our application doesnโ€™t use (like the camera or microphone) to prevent them from being weaponized.

CORS is often misunderstood as a โ€œsecurity feature.โ€ In reality, it is a relaxation of security. Programmers manage this relaxation with surgical care.

  • Avoid the Wildcard: Never use Access-Control-Allow-Origin: * in production. It bypasses the Same-Origin Policy entirely.
  • Dynamic Origin Validation: If you must support multiple origins, validate the Origin request header against a strict allow-list on the server side.
  • Credentials Security: If Access-Control-Allow-Credentials is set to true, the origin cannot be a wildcard. This prevents malicious sites from making authenticated requests on behalf of your users.
  • Preflight Optimization: Use Access-Control-Max-Age to cache preflight (OPTIONS) responses, reducing latency without compromising security.

Every production response should include these headers to dictate how the browser handles your content.

The most powerful tool against XSS. It tells the browser exactly which scripts, styles, and images are allowed to load.

  • Tip: Start with a โ€œReport-Onlyโ€ policy to identify violations without breaking the site, then move to a strict policy that disallows inline scripts.

Ensures the browser only communicates with your server over HTTPS, even if the user types http://.

  • Tip: Include the includeSubDomains and preload directives to protect your entire domain ecosystem.

Prevents the browser from โ€œguessingโ€ the content type. This stops attackers from disguising a malicious script as a harmless image.

Prevents your site from being embedded in an <iframe> on another site, which is the primary defense against Clickjacking.

  • Tip: Use the CSP frame-ancestors directive for modern browsers, as it is more flexible than X-Frame-Options.

Tells the browser to disable specific hardware features (Camera, Geolocation, Microphone) to ensure they cannot be exploited even if an XSS vulnerability is found.


A Programmer knows that security headers should be applied consistently across the entire application.

  • Global Middleware: Donโ€™t set headers in individual controllers. Set them at the Load Balancer, API Gateway, or a global Middleware layer.
  • Verification Tooling: Use automated scanners (like securityheaders.com or OWASP ZAP) in your CI/CD pipeline to ensure that no deployment accidentally strips these headers.
  • Consistent Application: Ensure headers are applied to error pages and 404s, as these are often overlooked and can be used for attacks.

  • CORS Origins: Are we using an allow-list instead of a wildcard?
  • CSP Strictness: Does our CSP block unsafe-inline and unsafe-eval?
  • HSTS Policy: Is the max-age set to at least one year ($31,536,000$ seconds)?
  • Referrer-Policy: Are we using strict-origin-when-cross-origin to prevent leaking sensitive URLs to third parties?
  • Cookies: Are our security-sensitive cookies marked as HttpOnly, Secure, and SameSite=Strict?

โ€œThe browser is a chaotic environment. Security headers are the laws we provide to bring order to that chaos. A Programmerโ€™s job is to ensure those laws are strict, clear, and non-negotiable.โ€