[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



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/