[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[FD] Apache Struts2 REST Plugin Untrimmed `Accept` Header Tokens Break Content Negation Fallback
- To: "fulldisclosure@xxxxxxxxxxxx" <fulldisclosure@xxxxxxxxxxxx>
- Subject: [FD] Apache Struts2 REST Plugin Untrimmed `Accept` Header Tokens Break Content Negation Fallback
- From: Daniel Owens via Fulldisclosure <fulldisclosure@xxxxxxxxxxxx>
- Date: Thu, 29 Oct 2026 11:34:48 +0000
Description
The Apache Struts2 REST Plugin's
`DefaultContentTypeHandlerManager.getHandlerForResponse(HttpServletRequest,
HttpServletResponse)` splits the `Accept` header on commas and passes each
resulting token directly to `findHandler(String)` without trimming leading or
trailing whitespace. `findHandler(String)` only retries a trimmed lookup when
a token contains a semicolon (`;`), so a token that merely carries a leading
space has no such fallback and fails the direct map lookup.
Impact
Any client that sends a standard, comma-space-separated `Accept` header -- the
typical of most Hypertext Transfer Protocol (HTTP) client libraries -- triggers
this. As the lookup fails silently, `getHandlerForResponse()` falls through to
the `defaultExtension` handler instead of the content type the caller actually
requested, silently returning a representation that the client neither asked
for nor can necessarily parse. In deployments that rely on content negotiation
to select between differently-scoped representations of the same resource --
such as a minimal public representation served as the default extension against
a fuller representation only intended for a specific, explicitly-requested type
-- this fallback can cause the wrong representation to be returned, degrading
interoperability and, where the two representations differ in which fields they
expose, create a data-exposure vulnerability (insecure serialisation). While
attackers cannot choose the default representation
, they can abuse this to search for insecure serialisation, data exposures,
and similar information disclosure issues, as well as to see if there is a
difference between various representations and the default. Importantly, the
default representation and ensuing serialisation library can be used against
the information system (a trivial task).
Examples
Sample Code
`getHandlerForResponse(HttpServletRequest, HttpServletResponse)` splits the raw
`Accept` header on commas and sends each token to `findHandler(String)`, whose
direct map lookup only has a trimming fallback when the token contains a
semicolon, as shown below.
```java
/**
* Gets the handler for the response by looking at the extension of the
request
* @param request The request
* @return The appropriate handler
*
* WW-4588: modified to get a handler for the response side and auto
generate the response type
* from the Accept: header
*
*/
@Override
public ContentTypeHandler getHandlerForResponse(HttpServletRequest request,
HttpServletResponse res) {
String extension = getExtensionIfPresent(request.getRequestURI());
if (extension == null) {
extension = defaultExtension;
final String acceptHeader = request.getHeader("accept") ;
if (acceptHeader != null) {
final String[] types = acceptHeader.split(",");
for (final String type : types) {
final ContentTypeHandler handler = findHandler(type);
if (handler != null) {
return handler;
}
}
}
}
return handlersByExtension.get(extension);
}
private ContentTypeHandler findHandler(final String type) {
ContentTypeHandler handler = handlersByContentType.get(type);
if (handler == null) {
// strip off encoding and search again (e.g.,
application/json;charset=ISO-8859-1)
final int index = type.indexOf(';');
if (index != -1) {
return handlersByContentType.get(type.substring(0,
index).trim());
}
}
return handler;
}
```
Code snippet from `struts2-rest-plugin`'s
plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java,
lines 128-158
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/