X-Content-Type-Options: nosniff Header Filter
Explains the NoSniffHeaderFilter, which adds the 'X-Content-Type-Options: nosniff' header to all Admin API responses to prevent MIME-sniffing by browsers.
Overview
The NoSniffHeaderFilter is a security component in the Admin API that automatically adds the X-Content-Type-Options: nosniff HTTP header to every response.
This filter solves the problem of MIME-type sniffing by web browsers. Some browsers attempt to guess the content type of a response by inspecting its body, overriding the Content-Type header. This can create a security vulnerability if a browser misinterprets a data-only response (like JSON) as active content (like HTML or JavaScript) and executes it. By setting the X-Content-Type-Options: nosniff header, the filter instructs browsers to trust the Content-Type header and never attempt to sniff the content.
The filter is part of the Admin API's servlet filter chain and is designed to execute very early in the process. This ensures that all responses, including early rejections for authentication (401) or CSRF (403) failures, include this protective header.
NOTE
This filter is specific to the Admin API and its JSON responses. It does not manage Content-Security-Policy (CSP) headers, which are the responsibility of the Admin UI component that serves user-facing pages.
How it works
The NoSniffHeaderFilter is implemented as a Spring @Component that extends OncePerRequestFilter, ensuring it is executed exactly once for each request that enters the filter chain.
Its position in the filter chain is set with a high precedence (Ordered.HIGHEST_PRECEDENCE + 10), causing it to run before most other application filters. This guarantees that its logic applies even if a subsequent filter in the chain rejects the request.
The core logic resides in the doFilterInternal method. For every request, it performs the following steps:
- It accesses the
HttpServletResponseobject. - It calls
response.setHeader("X-Content-Type-Options", "nosniff")to add the header. - It invokes
filterChain.doFilter(request, response)to pass the request and the modified response object to the next filter in the chain.
The filter is also configured to apply to error dispatches by overriding shouldNotFilterErrorDispatch() to return false. This ensures that container-generated error pages receive the nosniff header, providing consistent security behavior across all response types.
The following diagram illustrates the filter's position in the request-response flow.
sequenceDiagram
participant C as API Consumer
participant S as Servlet Container
participant F as NoSniffHeaderFilter
participant R as Rest of Filter Chain
C->>S: HTTP Request
S->>F: doFilterInternal()
F->>S: response.setHeader("X-Content-Type-Options", "nosniff")
F->>R: filterChain.doFilter()
R-->>F: Processing continues
F-->>S: Control returns
S-->>C: HTTP Response (with header)Example
The filter's effect is visible on every response from the Admin API. An API consumer making a request to any Admin API endpoint will receive the X-Content-Type-Options header in the response.
For example, a successful request might produce a response with the following headers:
HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
Content-Length: 123
{
"status": "success"
}
Even an error response, such as one for an unauthenticated request, will include the header:
HTTP/1.1 401 Unauthorized
X-Content-Type-Options: nosniff
Content-Length: 45
{
"error": "Authentication required"
}
Configuration
The NoSniffHeaderFilter is not externally configurable. Its behavior is defined by internal constants within the class.
| Name | Type | Value | Description |
|---|---|---|---|
ORDER | int | Ordered.HIGHEST_PRECEDENCE + 10 | The execution order of the filter in the servlet filter chain. This low numerical value ensures it runs very early, before most other filters. |
HEADER | String | "X-Content-Type-Options" | The name of the HTTP response header that the filter sets. |
VALUE | String | "nosniff" | The value set for the X-Content-Type-Options header, which disables MIME-type sniffing in compliant browsers. |
See Also
- CSRF Protection: This filter works alongside other security measures like Cross-Site Request Forgery (CSRF) protection in the Admin API.
- Identity Provider Integration: The filter's early execution ensures its header is present even on authentication-related error responses from an Identity Provider (IdP).
