Skip to main content

Runtime Response Security Headers

Learn how the runtime adds security headers like X-Content-Type-Options and a restrictive Content-Security-Policy to all API responses to mitigate risks.

Overview

The ResponseSecurityHeadersFilter is a servlet filter that automatically adds security-related HTTP headers to every response generated by the API runtime. Its primary purpose is to mitigate security vulnerabilities that could arise if a backend service returns an HTML response (e.g., an error page) that is then rendered by a browser in the context of a privileged user session, such as an administrator's.

This filter runs for every request and has the highest execution precedence, ensuring that its security headers are applied to all responses, including early rejections from other filters and container-generated error pages. It adds two key headers: X-Content-Type-Options and Content-Security-Policy.

By applying a strict, sandboxing Content Security Policy, the filter neutralizes potentially malicious active content (like JavaScript) without modifying the response body or the Content-Type header from the backend. This preserves the byte-fidelity contract of the API gateway while hardening the platform against cross-site scripting (XSS) and other content injection attacks.

How It Works

The ResponseSecurityHeadersFilter is implemented as a Spring OncePerRequestFilter and is registered to run first in the servlet filter chain for every incoming request.

The process for each request is as follows:

  1. The ResponseSecurityHeadersFilter intercepts the request before any other application logic.
  2. It immediately adds the X-Content-Type-Options and Content-Security-Policy headers to the HttpServletResponse.
  3. It then wraps the HttpServletResponse object with an internal SecurityHeadersGuard wrapper.
  4. Finally, it passes the request and the wrapped response to the next filter in the chain.

The SecurityHeadersGuard wrapper is critical to the filter's function. It prevents any downstream component—such as the gateway handler relaying headers from a backend SOAP service—from overriding or duplicating the security headers set by this filter.

  • The wrapper intercepts calls to setHeader() and addHeader(). If the header name matches X-Content-Type-Options or Content-Security-Policy (case-insensitively), the call is silently ignored.
  • The wrapper also intercepts calls to reset(). If the response is reset, the wrapper first calls the underlying reset() method and then immediately re-applies the two security headers to the cleared response.

This mechanism guarantees that every response, whether successful or an error, leaves the runtime with these specific security policies enforced.

sequenceDiagram
    participant C as API Consumer
    participant F as ResponseSecurityHeadersFilter
    participant G as SecurityHeadersGuard Wrapper
    participant D as Downstream Filters & Handlers

    C->>F: HTTP Request
    activate F
    F->>G: Creates wrapper for response
    Note over F,G: Sets initial security headers
    F->>G: setHeader("X-Content-Type-Options", "nosniff")
    F->>G: setHeader("Content-Security-Policy", "...")
    F->>D: Forwards request with wrapped response
    activate D
    Note over D: Logic attempts to set a<br/>conflicting backend header
    D->>G: setHeader("Content-Security-Policy", "backend-policy")
    activate G
    Note over G: Ignores request to<br/>overwrite owned header
    deactivate G
    D-->>F: Returns
    deactivate D
    F-->>C: HTTP Response with<br/>guaranteed security headers
    deactivate F

IMPORTANT

This filter is also configured to apply to error dispatches. This ensures that container-generated error pages (e.g., for a 404 or 500 error that occurs before the application can write a response) are also protected by these security headers.

Response Headers

The filter adds the following two HTTP headers to all runtime responses. These headers are not externally configurable.

Header NameValueDescription
X-Content-Type-OptionsnosniffInstructs browsers not to perform MIME-type sniffing. This forces the browser to adhere to the Content-Type header provided by the server, preventing it from misinterpreting a response as renderable HTML or script.
Content-Security-Policydefault-src 'none'; frame-ancestors 'none'; sandboxApplies a strict Content Security Policy with three directives:<ul><li>default-src 'none': Blocks the loading of any sub-resources (scripts, stylesheets, images, etc.).</li><li>frame-ancestors 'none': Prevents the response from being embedded in a <frame>, <iframe>, <embed>, or <object>, mitigating clickjacking attacks.</li><li>sandbox: Renders the content in a sandboxed environment, disabling scripts, form submissions, plugins, and other potentially dangerous capabilities.</li></ul>

Example Headers

An API consumer will see these headers on every response from the runtime, including both successful API calls and error pages.

HTTP/1.1 200 OK
Content-Type: application/json
Content-Security-Policy: default-src 'none'; frame-ancestors 'none'; sandbox
X-Content-Type-Options: nosniff
...

{
  "data": "..."
}

Troubleshooting

Backend Headers Are Not Propagated

If a backend service returns its own X-Content-Type-Options or Content-Security-Policy header, it will be dropped by the SecurityHeadersGuard wrapper. The platform intentionally enforces its own uniform, strict policy for these headers on all runtime responses. This behavior is by design and cannot be overridden. If you are an API publisher, do not rely on the runtime to propagate custom CSP or X-Content-Type-Options headers from your backend services to the API consumer.

See Also

  • The TenantContextFilter, which is another security-related filter that runs immediately after ResponseSecurityHeadersFilter.
  • The Gateway SOAP Handler, which relays responses from backend services and whose relayed headers are subject to the policies enforced by this filter.
Tagsguides

All SOAP-to-REST docs