CORS, CSP, HSTS, and Other HTTP Headers
Back to Learn
FAACChapter 26

Corporate API Fundamentals and Architecture

CORS, CSP, HSTS, and Other HTTP Headers

How browsers, applications, and gateways use HTTP policies to control origins, content, transport, isolation, privacy, and caching

In-depth edition - study material and professional reference

Browser and APIs protected by origin, content, and secure transport policies

Headers as declarative policies between server, gateway and browser

CORS, CSP, HSTS and other headers as declarative layers of protection
Opening figure - Headers form a declarative layer of protection, but they act on different problems.

Central principle

Headers do not correct authorization, authentication or business logic; they govern behavior of customers and intermediaries.

In-depth edition - study material and professional reference

Chapter presentation

The previous chapter presented the OWASP API Security Top 10 and showed that protecting an API depends on distributed controls between client, browser, gateway, backend, identity, network and operation. This chapter delves into a specific part of that defense: the HTTP headers that instruct browsers and intermediaries how to handle origins, executable content, secure transport, context isolation, privacy, and caching.

, , and are often grouped together as security headers, but they solve very different problems. defines when a browser can expose a response obtained from another source to a web application. limits script fonts, styles, frames, connections and other resources, reducing the impact of content injection. instructs the browser to use HTTPS for a host during a defined period of time. None of them replace authentication, authorization, data validation or fixing vulnerabilities on the backend.

Other headers complement this model. -Policy limits the information sent on Referer; Permissions-Policy controls browser resources; X-Content-Type-Options reduces unexpected MIME interpretations; frame-ancestors and X-Frame-Options handle embedding in frames; , and participate in cross- isolation; Cache-Control protects sensitive responses from improper storage; Cookie attributes reduce exposure to scripts, insecure transport and cross-site requests.

The goal is to build an accurate mental model for implementation and troubleshooting. The reader should know how to distinguish an actual API failure from a browser decision, recognize configuration errors in API Gateways and CDNs, plan secure rollout of restrictive policies, and test protections without relying solely on automatic scanners.

How to study this chapter

For each header, identify five elements: who sends, who applies, what asset protects, what threat mitigates, and what legitimate behavior can be broken. This analysis avoids the dangerous practice of copying a set of headers without understanding their effects.

Learning Objectives

  • Explain , site, , and browser security boundary.
  • Describe simple requests, , credentials and cache.
  • Correctly configure Access-Control-Allow- and related headers.
  • Differentiate from authentication, CSRF, firewall and server-server security.
  • Design Content Security Policy with directives, nonces, hashes and report-only deployment.
  • Understand , includeSubDomains, preload and incorrect rollout risks.
  • Apply X-Content-Type-Options, frame-ancestors, -Policy and Permissions-Policy.
  • Relate , and to cross- isolation.
  • Set Cache-Control and cookie attributes for sensitive responses and sessions.
  • Implement, test and observe headers in applications, gateways and CDNs.

Chapter structure

  • 26.1 Browser Security Model and Declarative Headers
  • 26.2 , website and
  • 26.3 : purpose and decision flow
  • 26.4 Simple and requests
  • 26.5 request and response headers
  • 26.6 Credentials, cookies, Authorization and wildcards
  • 26.7 in API Gateways and frequent errors
  • 26.8 Content Security Policy: model and directives
  • 26.9 Nonces, hashes, strict-dynamic and inline scripts
  • 26.10 Reporting and gradual implementation of
  • 26.11 HTTP Strict Transport Security
  • 26.12 Clickjacking, and frame protection
  • 26.13 -Policy and Permissions-Policy
  • 26.14 , and
  • 26.15 Cache-Control, Clear-Site-Data and cookies
  • 26.16 Obsolete headers, troubleshooting and labs
  • Summary, checklist, exercises, glossary and references

26.1 Browser Security Model and Declarative Headers

Browsers run code provided by multiple sources and need to prevent a malicious page from reading data from another application just because the user is authenticated there. This protection is not implemented by a single mechanism. The establishes a basic boundary; allows controlled exceptions; restricts the content that can be loaded or executed; cookies have their own attributes; and isolation policies reduce sharing between contexts.

Security headers are declarative: the server sends a policy and the compliant agent decides how to apply it. This creates an important difference between browser security and API security. A client written in Java, Python, or curl can completely ignore and , because these mechanisms were not designed as universal access control. The API still needs to validate credentials, authorization, schema and business rules on every request.

The gateway is an efficient point for standardizing headers, but it does not automatically know all of the application's needs. A suitable depends on the scripts, frames and connections actually used by each front-end. depends on consumer origins and credential policy. Cache-Control depends on sensitivity and shareability. Therefore, the platform can provide defaults and guardrails, while the product maintains ownership of the specific policy.

Essential distinction

does not protect the API against external calls; it controls whether a browser delivers the response to JavaScript from another source. An attacker or server-server system is still able to send the request. Authorization and protection from abuse remain mandatory.

26.2 , website and

A source is conceptually defined by the trio of schema, host and port. https://app.empresa.com and https://api.empresa.com have different hosts and therefore different origins. https://app.empresa.com and http://app.empresa.com differ in schema. https://app.empresa.com:443 and https://app.empresa.com:8443 differ in port. The URL path does not participate in the .

The concept of a website is related, but not identical. Mechanisms like SameSite in cookies work with the notion of site, while uses . Two subdomains can be same-site and even cross- . This difference explains scenarios where a cookie is sent but JavaScript cannot read the response because the policy did not authorize the .

The limits reading and interaction between contexts of different origins. It does not prevent all cross- data sending: forms, images, links and other resources historically make requests. The main protection is in restricting the script's ability to observe content and manipulate objects from another source. is the protocol that allows the server to declare controlled exceptions for certain operations.

Table 1 - Source is determined by scheme, host, and port, not path.
URL AURLBSame origin?Reason
https://app.example.comhttps://app.exemplo.com/perfilYesSame scheme, host and port.
https://app.example.comhttps://api.exemplo.comNoDifferent host.
http://app.example.comhttps://app.example.comNoDifferent scheme.
https://app.example.comhttps://app.exemplo.com:8443NoDifferent port.

26.3 : purpose and decision flow

Cross- Resource Sharing is a protocol integrated into the browser's fetch model. When a script tries to access an API from another , the browser appends the header. The response must contain headers that indicate whether that source, method, set of headers, and use of credentials are allowed. When the policy does not match, the request can even reach the server, but the response is not made available to JavaScript.

This feature produces a frequent symptom: the backend records success, the gateway returns 200, but the browser console shows error. There is no contradiction. The server processed the operation; the browser blocked the response from being displayed. Therefore, operations with side effects cannot depend on as protection against CSRF or improper actions.

The browser can directly send the request when it meets the criteria for a simple request. In other situations, with OPTIONS. asks the server whether the intended method and headers are accepted before sending the actual operation. The positive response may be stored in a specific browser cache for a limited period of time.

with : browser negotiates before sending the actual operation

Browser negotiating preflight OPTIONS with API before the actual request
Figure 1 - negotiates permission; The final decision to display the response belongs to the browser.

26.4 Simple and requests

The term simple request does not mean that the operation is safe for the business. It indicates that the browser can send it without to maintain compatibility with historical Web standards. Methods such as GET, HEAD and POST can participate when the headers and Content-Type remain within the set allowed by the protocol. A POST application/json, for example, normally causes .

uses OPTIONS and includes Access-Control-Request-Method. If the script intends to send unsafelisted headers, the browser also includes Access-Control-Request-Headers. The server responds with authorized methods and headers. The actual request is only released when the response satisfies the browser's checks.

is not authentication. Some architectures make the mistake of requiring a token in OPTIONS or forwarding to backends that don't know . Since is a policy query performed before the actual request, gateways usually treat it specifically. However, responding permissively to any source and method also creates risk; policy needs to be derived from trusted configuration.

and response example

OPTIONS /clientes/123 HTTP/1.1
Host: api.empresa.example
Origin: https://portal.empresa.example
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: authorization, content-type
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://portal.empresa.example
Access-Control-Allow-Methods: GET, PUT
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Max-Age: 600
Vary: Origin

26.5 request and response headers

identifies the of the context that initiated the request. Access-Control-Allow- tells you which is authorized to read the response. The value can be a specific or wildcard in non-credential scenarios. When the is dynamic, the server must validate the received value against an and return exactly the approved source, never reflecting any value without checking.

Access-Control-Allow-Methods and Access-Control-Allow-Headers mainly participate in . Access-Control-Expose-Headers allows JavaScript to read response headers that do not belong to the set exposed by default. Access-Control-Max-Age influences cache, subject to browser limits. Access-Control-Allow-Credentials allows credentialed responses when combined with an explicit source.

: is important when the response can change depending on the requesting and passes through shared caches. Without this indication, a cache may reuse a response that contains a specific Access-Control-Allow- for another . On platforms with a CDN or gateway, the cache key and policy must be designed together.

Table 2 - The CORS set forms a negotiation protocol, not an isolated header.
HeaderDirectionFunction
OriginRequestIdentifies the origin of the requesting context.
Access-Control-Allow-OriginResponseAuthorizes a source or, in limited cases, the wildcard.
Access-Control-Allow-Methodspreflight responseDeclares allowed methods.
Access-Control-Allow-Headerspreflight responseDeclares headers allowed in the actual request.
Access-Control-Expose-HeadersResponseExposes additional headers to JavaScript.
Access-Control-Allow-CredentialsResponseAllows response with credentials in CORS context.
Access-Control-Max-Agepreflight responseControls preflight cache duration.

A can involve cookies, client certificates, or agent-controlled HTTP credentials. In fetch, credentials mode determines whether credentials are sent and whether responses with Set-Cookie are considered. For JavaScript to receive a credentialed cross- response, the server needs to return Access-Control-Allow-Credentials: true and an explicit .

The wildcard in Access-Control-Allow- cannot be used to expose credentialed responses. This restriction reduces the risk of an arbitrary website reading data associated with the user's session. It is also inappropriate to generate Access-Control-Allow- by copying the received without validation. Unrestricted reflection turns policy into universal authorization in disguise.

and SameSite cookie attributes are related but not equivalent. The cookie may not be sent because of SameSite, Secure, or third-party rules before is even evaluated. In another scenario, the cookie is sent and the server processes the request, but the browser blocks reading the response. Diagnosis needs to look at cookie sending, , actual response and browser console separately.

Rule of thumb

For cookie-based session APIs, treat , SameSite, CSRF, and policy as supplemental controls. For APIs with a bearer token, validate token and authorization normally; The fact that the browser requires does not make the endpoint secure from clients outside the browser.

26.7 in API Gateways and frequent errors

API Gateways can centralize , respond without reaching the backend, and apply allowlists by environment, product, or API. This centralization reduces duplication, but requires defining ownership. If gateway and backend add different headers, the response may contain duplicate or contradictory values. Some browsers reject responses with multiple Access-Control-Allow- .

The policy must also be applied to error responses. An API that returns only in 2xx can cause the browser to hide the body of 401, 403 or 500, making diagnosis and customer experience difficult. The on-error section or equivalent of the gateway needs to produce the same relevant headers without opening additional permissions.

Another common mistake is allowing sources via insecure textual comparison. Tests like endsWith("company.com") can accept malicious domains. The value needs to be interpreted as and compared with exact or carefully defined subdomain rule. Regular expressions must be anchored and tested against schemas, ports, case normalization, and null sources when applicable.

Table 3 - CORS errors are often architectural errors and not just syntax errors.
FailureSymptomCorrection
OPTIONS requires authenticationPreflight returns 401 before the actual call.Treat OPTIONS according to CORS policy and not as a business operation.
CORS only in 2xx responsesFrontend sees generic error.Also apply headers to the error flow.
Origin reflected without validationAny website receives permission.Compare with trusted allowlist.
Gateway and backend duplicate headersBrowser rejects ambiguous response.Define a single emission point.
No Vary: Origin cachedOrigin receives policy from another origin.Adjust Vary and cache key.

26.8 Content Security Policy: model and directives

Content Security Policy defines restrictions on the resources that a page can load or run. The policy can be sent in the Content-Security-Policy header or, in specific cases, by meta element. The header has greater scope and is the preferred form for complete policies. does not fix the vulnerability that allowed the injection, but it can reduce what the injected content can do.

Directives are specialized. default-src provides fallback for various resource types. script-src controls scripts; style-src controls styles; img-src images; connect-src connections made by fetch, XHR, WebSocket and related mechanisms; font-src fonts; frame-src content loaded in frames; frame-ancestors define who can embed the page; object-src controls plugins; base-uri restricts the base URL; form-action limits form targets.

A policy must be minimal and compatible with actual application. Widely authorizing https: or using unsafe-inline and unsafe-eval reduces protection. At the same time, blocking resources without inventory can break legitimate login, telemetry, fonts, integrations, and functionality. Therefore, must be built from inventory, testing and observation, not copied from another application.

: each resource is compared with the policy before being loaded or executed

HTML document using CSP directives to control scripts, frames and connections
Figure 2 - The policy compares each resource type with the corresponding policy.

Restrictive Policy Example

Content-Security-Policy:
  default-src 'none';
  script-src 'self' 'nonce-R4nd0mBase64';
  style-src 'self';
  img-src 'self' data:;
  connect-src 'self' https://api.empresa.example;
  frame-ancestors 'none';
  base-uri 'none';
  form-action 'self'

26.9 Nonces, hashes, strict-dynamic and inline scripts

Inline scripts are a major source of risk because an HTML injection can turn into JavaScript execution. Removing inline scripts and serving static files is the simplest solution when possible. When the application requires inline scripting, a cryptographically unpredictable can be generated per response and included in both the and the authorized script element.

Hashes allow you to authorize inline content whose text is known and stable. The browser calculates the hash of the block and compares it with the policy value. Small changes to the content require re-hashing. Nonces are best suited for dynamic content, as long as they are not reused or automatically inserted into user-controlled content.

strict-dynamic allows trusted scripts loaded by or hash to propagate trust to scripts they add, reducing dependency on host allowlists. This strategy requires compatibility testing and understanding of the application bootstrap. unsafe-inline and unsafe-eval should be treated as temporary leases with a removal plan, not as a default configuration.

Table 4 - Nonces and hashes allow reducing dependence on unsafe-inline.
MechanismWhen to useMain care
External file in selfApplication controls the scripts on the host itself.Host compromise still compromises scripts.
NonceResponse-authorized dynamic inline scripting.Generate unpredictable and unique value per response.
HashStable and well-known inline block.Any change requires updating the hash.
strict-dynamicReliable Bootstrap loads dependencies.Validate compatibility and chain of trust.

26.10 Reporting and gradual implementation of

Content-Security-Policy-Report-Only allows you to observe violations without blocking resources. It's useful for inventorying dependencies and discovering inline code, third-party domains, and undocumented flows. However, report-only does not protect the user; it is an implementation stage. A mature organization sets a deadline for turning observations into effective policy.

Reports may contain sensitive URLs and information. The collection endpoint needs volume control, retention, and privacy. Events should be aggregated by policy, , and application version to distinguish attacks, browser extensions, noise, and actual regressions. Effective policy and observation policy can coexist, allowing progressive hardening.

The recommended rollout starts with inventory, goes through report-only, fixes legitimate violations, blocks lower-risk policies, and progresses to restrictive policy. changes must participate in the pipeline and be tested with critical journeys, because an incorrect header can make the entire front-end unavailable even if the API remains healthy.

is not trusted domain list

Authorizing a domain means accepting all content it can serve in that context. Shared CDNs, upload endpoints, and third-party services expand the surface. Prefer specific nonces, hashes, and sources over overly broad allowlists.

26.11 HTTP Strict Transport Security

HTTP Strict Transport Security allows a host to declare that it should only be accessed via HTTPS. The browser stores the received policy in a valid HTTPS connection and, during max-age, transforms HTTP attempts to HTTPS before sending the request over the network. This reduces exposure to TLS downgrade and removal attacks after the host has been known to be secure.

The header has the max-age directive and can include includeSubDomains. The latter extends the policy to subdomains and requires full inventory: any subdomain without functional HTTPS may become inaccessible. The preload directive is used as a signal of intent to preload programs, but actual inclusion depends on requirements and processes external to the protocol.

does not fix expired certificate, incorrect hostname or invalid string. Instead, the browser must fail hard and not offer unsafe downgrade. First access remains a consideration when the host is not yet in the state; preload may reduce this window, but increases the long-term operational commitment.

changes future browser decisions to a known host

Browser learning HSTS and promoting HTTP to HTTPS
Figure 3 - Once learned, makes the browser prefer HTTPS and reject downgrade.

Examples of

Strict-Transport-Security: max-age=31536000; includeSubDomains
# Possible gradual deployment
Strict-Transport-Security: max-age=300
Strict-Transport-Security: max-age=86400
Strict-Transport-Security: max-age=31536000; includeSubDomains

26.12 Clickjacking, and frame protection

Clickjacking occurs when an application is embedded invisibly or deceptively on another website and the user interacts with controls without realizing the real context. The frame-ancestors directive is the modern mechanism for controlling which origins can frame the page. X-Frame-Options offers DENY and SAMEORIGIN, remaining relevant in compatibility, but lacks the flexibility of an list.

X-Content-Type-Options: nosniff instructs the browser to respect MIME types in relevant contexts rather than inferring executable content. This reduces scenarios where a resource served with the incorrect type is interpreted as a script or stylesheet. The header does not replace the correct Content-Type; both must be configured.

frame-ancestors protect documents that can be framed, while frame-src controls which frames the page itself can load. Confusing the two directives produces ineffective policies. It's also important to note that pure JSON APIs typically don't need to be frame-rendered, but portals, administrative consoles, and authentication pages need explicit protection.

Table 5 - Frame protection and content type are different responsibilities.
Header or directiveExampleUsage
CSP frame-ancestorsframe-ancestors 'none'Blocks incorporation from any source.
X-Frame-OptionsDENY or SAMEORIGINFraming protection compatibility.
X-Content-Type-OptionsnosniffReduces MIME sniffing on executable resources.
Content-Typeapplication/jsonDeclares the actual type of the payload.

26.13 -Policy and Permissions-Policy

The Referer header can reveal the URL of navigation or loading. When URLs contain identifiers, internal parameters, or sensitive structure, such sharing creates a privacy risk. -Policy controls how much of the information is sent. Policies like no- , same- , and strict- -when-cross- offer different levels of restriction.

The choice must balance privacy, anti-fraud, analytics and troubleshooting. Sending the full URL to third parties is rarely necessary. An -oriented policy reduces path and query exposure in cross- navigations, maintaining sufficient information for some controls. Sensitive data should not be in URLs, even with a restrictive policy, because it may appear in logs and history.

Permissions-Policy allows you to enable or disable browser features for the document and frames, such as camera, microphone, geolocation and fullscreen, depending on the supported set. The objective is to reduce available capabilities to own and third-party content. The old Feature-Policy nomenclature has been replaced; Configurations must use the current syntax and capabilities of the target agent.

Privacy Examples and Browser Capabilities

Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(self)
# More restrictive example
Referrer-Policy: no-referrer

26.14 , and

Cross- -Opener-Policy controls the relationship between a document and open or opened windows. By isolating context groups, it reduces attacks and interference that rely on cross-window references. Cross- -Embedder-Policy requires that embedded cross- resources are explicitly shareable by or , depending on the mode adopted.

Cross- -Resource-Policy allows a resource to declare whether it can be loaded by documents of the same , same site, or any permitted context. Together, and can produce cross- isolation, necessary for some powerful browser APIs. This configuration should be tested because third-party resources without proper headers may fail to load.

These headers are not replacements for or . controls programmatic access to responses; protects the resource against certain cross- loads; separates navigation contexts; defines incorporation requirements. The architecture needs to know which side publishes each policy and how third-party CDNs, images, fonts, and scripts behave.

Table 6 - Cross-origin policies complement each other, but protect different borders.
MechanismQuestion that answersExample
COOPWith which windows does this document share context group?Cross-Origin-Opener-Policy: same-origin
COEPWhat cross-origin features can be incorporated?Cross-Origin-Embedder-Policy: require-corp
CORPWho can upload this resource?Cross-Origin-Resource-Policy: same-site
CORSWhich source can access the response via browser?Access-Control-Allow-Origin: https://app...

26.15 Cache-Control, Clear-Site-Data and cookies

Sensitive responses may remain in the browser cache, proxy, or CDN. Cache-Control sets policies for storage and reuse. no-store is appropriate when no retention is acceptable; private allows private but not shared caching; no-cache requires revalidation before use; max-age defines freshness. Directives should be chosen by the semantics of the response, not by a single rule for the entire API.

Authentication does not automatically make a response uncacheable. Gateways and CDNs need to consider Authorization, cookies, and explicit rules. A custom response stored in a shared cache can leak data between users. On the other hand, disabling all cache indiscriminately can degrade performance and increase cost. The design must separate public, private, immutable and transactional content.

Clear-Site-Data allows you to request clearing of website data categories, such as cache, cookies and storage, depending on support. It can be useful in logout or incident response, but must be used carefully so as not to eliminate legitimate state or cause loops. Does not replace session revocation on the server.

Set-Cookie has security-relevant attributes. Secure restricts sending to secure channels; HttpOnly prevents access via JavaScript; SameSite influences sending in cross-site contexts; Path and Domain control scope; Max-Age and Expires define persistence. Session and authentication cookies must use minimal scope and not carry sensitive information in clear text.

Cache, clearing and cookie examples

Cache-Control: no-store
Clear-Site-Data: "cache", "cookies", "storage"
Set-Cookie: __Host-session=<value>; Path=/; Secure; HttpOnly; SameSite=Lax
# Versioned public content
Cache-Control: public, max-age=31536000, immutable
Table 7 - Cache and cookies require semantic precision; Intuitive names can be deceiving.
Directive or attributeOperational meaningCaution
no-storeDo not store the response.Useful for highly sensitive data.
privateAllow private, not shared cache.It may still remain on the user's device.
no-cacheStore, but revalidate before use.It does not mean no storage.
SecureOnly send cookies via a secure channel.It depends on correctly implemented HTTPS.
HttpOnlyPrevent access by JavaScript.It does not prevent automatic sending of the cookie.
SameSiteLimit sending in cross-site context.Choice depends on login and onboarding flow.

26.16 Obsolete headers and technology disclosure

Not every historically recommended header should continue to be implemented. X-XSS-Protection relates to older browser filters and does not replace . Public Key Pinning for HTTP created significant operational risks and was abandoned by browsers; HPKP should not be reintroduced as generic hardening. Expect-CT lost relevance with the evolution of Certificate Transparency and agent support.

Feature-Policy has been replaced by Permissions-Policy. X-Frame-Options remains useful for compatibility, but frame-ancestors offers modern control. Pragma is legacy for HTTP/1.0 caching and does not replace a clear Cache-Control policy. Header management needs to follow standards and real support, removing obsolete recommendations from corporate templates.

Headers such as Server and X-Powered-By can reveal products and versions. Reducing disclosure avoids providing unnecessary information, but should not be confused with fixing vulnerabilities. An attacker can identify technology by other signals. The priority continues to be patching, secure configuration, inventory and surface reduction.

Table 8 - Security requires removing obsolete controls, not just adding new headers.
ItemRecommended situationAlternative or observation
X-XSS-ProtectionDo not treat as main modern control.Use CSP and fix injection/XSS.
Public-Key-PinsDo not deploy.Manage certificates, CT and renewal automation.
Expect-CTDo not adopt as a new requirement.Use current Certificate Transparency ecosystem.
Feature-PolicyMigrate.Use Permissions-Policy.
X-Powered-ByRemove when possible.Does not replace hardening or patching.

26.17 Implementation in applications, gateways and CDNs

The application knows the content best and must participate in , cookies, cache, and journey-specific policies. The gateway can apply defaults, , , disclosure removal, observability and guardrails. The CDN can add or normalize headers, but their position in the stream needs to be understood to avoid overwriting and duplication.

A mature corporate policy defines a matrix by asset type: public JSON API, private API, static portal, authenticated application, administrative console, and file download. Each category receives baseline and approved exceptions. Applying the same to a JSON API and a SPA doesn't make sense; similarly, may be irrelevant for exclusively server-to-server integration.

Configuration as code and automated testing reduce drift. The pipeline can check presence, value, duplicity and consistency of headers. End-to-end tests must validate real behavior in the browser, because proxies, redirects, and error responses can change policy. In distributed environments, record which component added or removed each header.

Order of responsibility

Avoid multiple components by writing the same header without precedence rules. Clearly define whether application, gateway, ingress, CDN or web server is the authoritative source. Duplicity can be as dangerous as absence.

26.18 Troubleshooting and laboratories

The diagnosis starts in the browser: Network shows , redirects, cookies and headers; Console exhibits and violations; Application tools show cookies and storage. Then compare the response observed in the browser with curl or a server-server client. If curl works and fetch fails, the difference is probably in the browser's security model, not basic connectivity.

For , check , method, requested headers, OPTIONS response, actual response, credentials, , and duplicity. For , identify the violated policy, blocked URL, or hash, and effective policy. For , confirm that the header was received over HTTPS, the host state, and subdomain coverage. For cache, look at Age, Cache-Control, , and the component that served the response.

Laboratories must be performed in authorized environments. It is useful to set up two local sources on different ports, observe simple request and , activate credentials, test , deploy in report-only, introduce a blocked inline script, enable with short max-age and validate headers in gateway error responses.

Table 9 - The diagnosis must identify which agent applied the policy.
SymptomProbable layerEvidence to collect
CORS error, backend registered 200Browser policy or CORS response.Origin, ACAO, credentials, console and actual response.
Script does not run after deployCSP.Violated directive, nonce/hash and Report-Only.
Subdomain stopped after HSTSIncludeSubDomains coverage.HSTS and TLS status of the subdomain.
Another user's data appearsShared cache.Cache-Control, Vary, key and identity headers.
Legitimate Iframe has been blockedframe-ancestors/XFO.Effective policy and origin of the embedder.

Chapter summary

, and are distinct mechanisms. controls browser-mediated cross- access; restricts content loading and execution; establishes mandatory use of HTTPS after the policy is learned. None of them replace backend security, authentication, or authorization.

Complementary headers reduce other classes of risk: frame-ancestors and X-Frame-Options handle clickjacking; X-Content-Type-Options reduces ; -Policy improves privacy; Permissions-Policy limits capabilities; , and participate in isolation; Cache-Control and cookie attributes protect state and sensitive responses.

Correct deployment requires ownership, gradual rollout, browser testing, consistency in error responses and observability. Generic templates without understanding can break applications or produce a false sense of security. The policy needs to reflect the architecture and be revised as standards, browsers, and products evolve.

Next step of the course

The next chapter delves into Rate Limiting, Quotas and Throttling, mechanisms that control consumption, protect capacity and apply operational contracts in API Gateways.

Implementation checklist

  • has an explicit and does not arbitrarily reflect .
  • is handled correctly and does not rely on authentication of the actual operation.
  • headers also appear in the relevant error responses.
  • Per- variable responses use and coherent cache key.
  • was implemented with inventory, report-only and unsafe-inline/unsafe-eval removal plan.
  • Authoritative inline scripts use or hash correctly.
  • was gradually enabled and includeSubDomains was preceded by inventory.
  • frame-ancestors, nosniff, -Policy and Permissions-Policy have values appropriate to the asset.
  • , and were tested with third-party resources.
  • Cache-Control protects personalized and sensitive responses without blocking legitimate cache indiscriminately.
  • Session cookies use Secure, HttpOnly, SameSite, and minimal scope.
  • Obsolete headers have been removed from the baseline.
  • There is an authoritative component for each header and tests against duplication.
  • Critical journeys are tested in browser after gateway, CDN or application changes.

Exercises

  • Explain why does not prevent a server-server client from calling an API.
  • Differentiate and site and relate the difference to and SameSite.
  • Describe the complete flow for a PUT with Authorization and application/json.
  • Explain why Access-Control-Allow- : * does not work with credentialed response.
  • Propose a for a SPA that loads its own scripts and calls a specific API.
  • Compare , hash and unsafe-inline.
  • Explain the operational risk of includeSubDomains in .
  • Differentiate between frame-src, frame-ancestors and X-Frame-Options.
  • Compare no-store and no-cache with an example banking API.
  • Explain the differences between , , and .
  • Set up a gateway rollout plan for and without downtime.
  • List evidence needed to investigate a error that only occurs in production.

Glossary

Table 10 - Essential vocabulary of the chapter.
TermDefinition
AllowlistExplicit set of authoritative origins or sources.
CORSProtocol for controlled sharing of resources across origins in the browser.
CSPPolicy that restricts resources loaded and executed by a page.
COEPRequirements policy for cross-origin incorporation.
COOPIsolation policy between browsing contexts.
CORPResource declared policy on cross-origin upload.
Credentialed requestCORS request that uses credentials according to the client mode.
HSTSPolicy that requires the use of HTTPS for a certain period.
MIME sniffingInference of the content type by the browser in disagreement with the declared type.
NonceUnpredictable value used to authorize specific content in CSP.
OriginCombination of scheme, host and port.
PreflightOPTIONS query performed before certain CORS requests.
ReferrerInformation about the context that led to navigation or loading.
Same-Origin PolicySet of restrictions that separate contexts from different origins.
VaryHeader indicating request dimensions used to select cached representation.

Technical references

  • WHATWG. Fetch Standard - protocol, and fetch policies.
  • WHATWG. HTML Standard - , navigation and context policies.
  • W3C. Content Security Policy Level 3.
  • IETF. RFC 6797 - HTTP Strict Transport Security ( ).
  • IETF. RFC 7034 - HTTP Header Field X-Frame-Options.
  • IETF. RFC 9110 - HTTP Semantics.
  • IETF. RFC 9111 - HTTP Caching.
  • W3C. Policy.
  • W3C. Permissions Policy.
  • W3C. Clear Site Data.
  • OWASP. HTTP Headers Cheat Sheet and Cross Resource Sharing Cheat Sheet.

Update note

Browser headers and behavior evolve. Before adopting a corporate policy, validate the current specification, support of target browsers, and the behavior of the specific version of the gateway, ingress, CDN, and framework used.