Introduction to HTTP Security Headers
How, When, and Why to Use Them
Motivation
Nowadays, HTTP headers look like this:
HTTP 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Security-Policy: require-trusted-types-for 'script'; report-uri https://csp.withgoogle.com/csp/docs-tt
Content-Type: text/html; charset=utf-8
Referrer-Policy: strict-origin-when-cross-origin
Set-Cookie: SIDCC=...; Secure; HttpOnly
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Robots-Tag: noindex, nofollow, nosnippet
X-XSS-Protection: 1; mode=block
These headers are used by the browser for various needs. We want here to focus
on the headers related to security.
The goal is to understand what they mean, how and when to use them.
The presentation mainly focus on four of them (HSTS, CORS, CSP and X-Content-Type-Options) but you also have definitions of others presented in the slides.
The HTTP security headers are meant to enforce security at the browser level.
They are sent by the server to notify the browser of security restrictions or checks that need to be done.
HSTS (HTTP Strict Transport Security)
Definition
Informs browsers that the site should only be accessed using HTTPS, and that any future attempts to access it using HTTP should automatically be converted to HTTPS.
- Ensures that the website is only accessible over HTTPS.
- Converts all future HTTP requests to HTTPS.
- Prevents protocol downgrade attacks.
HSTS header is ignored by the browser when your site has only been accessed using HTTP.
Once your site is accessed over HTTPS with no certificate errors, the browser knows your site is HTTPS capable and will honor the Strict-Transport-Security header.
Browsers do this as attackers may intercept HTTP connections to the site and inject or remove the header.
Usage Example
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age
: Time in seconds the browser should remember to enforce HSTS (recommended: 1 year).includeSubDomains
(optional): Applies HSTS to all subdomains.preload
(optional): Submits the domain to the HSTS Preload List.
Mitigation
✅ Prevents protocol downgrade attacks
✅ Enforces HTTPS benefits
✅ Protects against Man-in-the-Middle (MitM) attacks
✅ Prevents cookie hijacking
When Is HSTS Not Useful or Problematic?
❌ Non-web services (irrelevant)
❌ Legacy browsers (not supported)
❌ Internal/local development (can cause issues)
❌ Static websites (but user input = not static!)
❌ Misconfigured SSL certificates (HSTS will block access entirely)
CORS (Cross-Origin Resource Sharing)
Definition
- Allows a server to specify which origins can access its resources.
- Prevents unauthorized cross-origin requests.
Preflight Requests
- A browser checks if a request is allowed before sending the actual request.
OPTIONS /resource/foo
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: x-requested-with
Origin: https://foo.bar.org
Key Headers
Header | Description |
---|---|
Access-Control-Allow-Origin | Defines allowed origins (e.g., https://example.com ) |
Access-Control-Allow-Methods | Specifies allowed HTTP methods (POST , GET , OPTIONS , etc.) |
Access-Control-Allow-Headers | Lists allowed request headers (X-PINGOTHER , etc.) |
Access-Control-Max-Age | Defines how long preflight request results are cached |
Access-Control-Allow-Credentials | Determines if cookies and authentication data are sent |
Why Use CORS?
✅ Controls who can make API requests
✅ Essential for APIs handling sensitive data
When Is CORS Not Required?
❌ Same-origin requests (API & frontend hosted on the same domain)
❌ Publicly accessible resources
❌ Internal/Intranet applications
CSP (Content Security Policy)
Definition
- Helps mitigate Cross-Site Scripting (XSS) and code injection attacks.
- Restricts content sources (scripts, media, styles, etc.).
Example Policies
Content-Security-Policy: default-src 'self'
- Only allows content from the site's own origin.
Content-Security-Policy: default-src 'self' example.com *.example.com
- Allows content from the main domain and subdomains.
Content-Security-Policy: default-src 'self'; img-src *; media-src example.org example.net; script-src userscripts.example.com
- Fine-tuned restrictions for scripts, media, and images.
When Should CSP Be Used?
✅ User-generated content (prevents XSS attacks)
✅ Third-party scripts/resources (enforce trusted sources)
✅ Sensitive data handling (protects against data theft)
When Is CSP Not Useful?
❌ Legacy browsers (not fully supported)
❌ Static websites (if no user input is involved)
CORS Vs. CSP
CSP
Control and limit the sources from which content can be loaded on your webpage,
particularly to prevent XSS and other types of code injection attacks.
CORS
When the web application needs to make requests to an API or a resource on a
different origin.
CSP | CORS | |
---|---|---|
Scope | Manages what types of content (scripts, images, styles) can be loaded and from which sources. | Manages cross-origin requests, determining which external domains can access server resources. |
Effect on Script Execution | Blocks inline scripts, or scripts from unauthorized sources if not explicitly allowed. | Doesn't affect script execution on the client-side but controls whether cross-origin requests are permitted. |
Browser Behavior | Instructs browsers to enforce resource loading policies. | Instructs browsers whether to allow or block cross-origin requests. |
Failure Impact | Incorrect CSP configuration can break site functionality if legitimate resources are blocked. | Incorrect CORS configuration can expose resources to unintended origins or restrict legitimate access. |
X-Content-Type-Options
Definition
Marker used by the server to indicate that the MIME types advertised in the
Content-Type
headers should be followed and not be changed.
Usage
X-Content-Type-Options: nosniff
nosniff
: blocks incorrect content types. If theContent-Type
doesn’t match the actual content, the browser will block the resource.
Mitigation
✅ Security Vulnerabilities: enforcing strict MIME type checking, nosniff
prevents browsers from making unsafe assumptions about the content of a
resource.
✅ Reduces Risk of Cross-Site Scripting: attackers might upload malicious
files to a website (like a script disguised as an image) and attempt to trick
the browser into executing them.
✅ Improves Content Security: websites that serve mixed types of content
(JS, CSS, images, …) benefit from nosniff
because it adds an extra layer of
protection by ensuring that each type of file is handled properly.
Other Headers
Set-Cookie
with HttpOnly
and Secure
flags
Enhances cookie security. HttpOnly
prevents JavaScript access to cookies,
reducing XSS risk. Secure
ensures cookies are sent only over HTTPS.
Cache-Control (HTTP/1.1) / Pragma (HTTP/1.0)
Prevent sensitive information from being stored in caches by using values like
no-store
and no-cache
.
Clear-Site-Data (not universally supported)
Ensure that confidential information from your application is not stored by the
browser after a user logs out.
Permissions-Policy (previously Feature-Policy)
Define permissions for specific browser features and APIs on the current page.
It can be used to control application functionality, but the main use case is to
restrict access to privacy-related features like microphone, camera, or
geolocation APIs.
Cross-Origin-Opener-Policy
Focuses on isolating the browsing context to improve security and prevent
cross-origin interference.
Cross-Origin-Embedder-Policy
Ensures that a document can only load cross-origin resources that are explicitly
marked for embedding, preventing cross-origin data leaks.
Cross-Origin-Resource-Policy
Allows control over which origins can load a particular resource, limiting
unauthorized cross-origin access.
Referrer-Policy
Controls how much referrer information should be included with requests. Values
like no-referrer
or strict-origin-when-cross-origin
help minimize
information leakage.
A user navigates from https://securebank.com/account?user=12345 to an external
site https://external.com, the browser might include the full URL with sensitive
query parameters.
By default in the header: :::
Referer: https://securebank.com/account?user=12345
With Referrer-Policy: strict-origin-when-cross-origin
Referer: https://securebank.com
Deprecated Headers
You may still encounter them for legacy reasons.
You should not use them in modern applications (no more support + some of them are buggy).
X-Frame-Options
X-XSS-Protection
Public-Key-Pins
Expect-CT
Conclusion
- Browsers act as the first line of defense against client-side attacks (XSS, CSRF, Clickjacking, etc.).
- Security headers help protect users by enforcing better security policies.
- Proper implementation is key—misconfiguration can lead to security risks.
Help your browser!