Introduction
When a browser connects to a web application, the server returns more than the HTML, JSON, or files the application requested. The HTTP response also contains instructions that influence how the browser handles that content.
Security-related response headers are one layer of those instructions. They can restrict where scripts and other resources are loaded from, enforce HTTPS, control framing, reduce information exposed through referrers, and disable browser features that an application does not need.
These controls do not make an application secure by themselves. They are defensive boundaries around the application and the browser. Their value depends on whether they are present, correctly configured, and appropriate for the application's actual architecture.
What Security Headers Actually Do
Security headers are delivered as part of an HTTP response. A browser reads them and applies the specified policy to the document, its resources, or subsequent requests.
During an external assessment, these headers are useful because they provide an immediate view of several browser-side security controls without requiring access to the application's source code.
A response might look like this:
Content-Security-Policy
Content-Security-Policy, or CSP, defines which sources a browser is permitted to use for content such as scripts, stylesheets, images, fonts, frames, and connections.
A restrictive CSP can reduce the impact of certain cross-site scripting attacks by preventing injected content from loading arbitrary external resources or executing scripts outside the policy.
CSP is particularly important because a policy that technically exists can still provide limited protection if it contains broad source expressions or unsafe allowances. The policy needs to reflect the application's legitimate resource requirements rather than simply allowing everything required to make the page work.
For example, a basic policy might restrict resources to the application's own origin:
Strict-Transport-Security
Strict-Transport-Security, commonly called HSTS, tells a browser that an application should only be accessed over HTTPS for a specified period.
This is different from simply redirecting HTTP traffic to HTTPS. A redirect happens after an HTTP request has already been made. HSTS allows a browser that has received the policy to avoid making future HTTP connections to the protected host.
A typical deployment might specify a one-year policy:
X-Content-Type-Options
X-Content-Type-Options controls whether a browser is allowed to perform MIME type sniffing.
The commonly deployed value is nosniff. This instructs browsers to respect the Content-Type supplied by the server instead of attempting to interpret the response as another content type.
The header is simple, but it removes unnecessary ambiguity from how browsers process server responses.
X-Frame-Options
X-Frame-Options controls whether a page can be embedded inside a frame.
This is relevant to clickjacking attacks, where an attacker places a legitimate application inside another page and attempts to manipulate where a user clicks.
A strict configuration can prevent framing entirely:
Frame Protection with CSP
Modern applications can also control framing through the frame-ancestors directive in Content-Security-Policy.
Unlike X-Frame-Options, frame-ancestors can express more flexible policies about which origins are permitted to embed a page.
For an application that should only be framed by itself, the policy can be written as:
Referrer-Policy
Referrer-Policy controls how much information a browser includes in the Referer header when navigating from one location to another.
This becomes relevant when URLs contain information that should not be unnecessarily disclosed to another origin. The URL itself might contain paths, identifiers, or other application-specific data.
A commonly used policy provides the full origin for cross-origin requests while avoiding transmission of the complete path:
Permissions-Policy
Permissions-Policy allows an application to control access to browser capabilities such as the camera, microphone, and geolocation.
An application that does not use a particular browser capability generally has little reason to expose that capability to every document or embedded resource.
For example, an application that does not require these three features can explicitly disable them:
What Missing Headers Tell an Assessor
A missing header is not automatically a vulnerability. The security impact depends on what the application does, which browser features it relies on, and whether another control already addresses the same threat.
For example, the absence of X-Frame-Options deserves different consideration for an application containing sensitive authenticated actions than it does for a completely static informational page.
The useful question during an assessment is therefore not simply whether a header exists. The question is whether the application has an appropriate browser-side control for the threat it is exposed to.
Assessment Methodology
Start by examining the HTTP responses returned by the application's main pages and important application endpoints. Do not assume that a framework, reverse proxy, CDN, or hosting provider has configured security headers correctly.
Record the headers returned by the application and compare them with the application's actual functionality. Check whether HTTPS is enforced, whether framing is controlled, whether content sources are restricted, and whether unnecessary browser capabilities are disabled.
Where a policy is present, review the policy itself. A CSP with broad allowances may provide substantially less protection than its presence alone suggests. Likewise, HSTS settings should be reviewed in the context of the application's subdomains and deployment model.
The objective is to understand the application's effective browser security policy rather than to produce a checklist of headers.
Common Misconfigurations
One common mistake is treating the presence of a header as proof that the associated security control is correctly implemented.
CSP is a good example. A policy may exist while still permitting overly broad script sources or other unsafe behaviour. HSTS can also be deployed with settings that do not match the application's subdomain architecture.
Another mistake is applying a generic security-header template without understanding the application. Security policies should support the application's real functionality. A policy that breaks legitimate features is not a successful security control.
Conclusion
Security headers are a relatively small part of an application's overall security architecture, but they provide an important browser-side layer of defence.
They can restrict resource loading, enforce HTTPS, control framing, reduce unnecessary information exposure, and limit access to browser capabilities.
For security assessments, they also provide useful evidence about how an application has been configured. The important step is not simply identifying missing headers, but determining whether the application's actual security requirements are being addressed by appropriate controls.