Checkmarx - How to validate and sanitize HttpServletRequest .getInputStream to pass checkmarx scan

27k views Asked by At

Following are checkmarx issue details Unrestricted File Upload

Source Object : req (Line No - 39)

target Object : getInputStream (Line No -41)

    public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter
{

    //...
38 public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
39            throws AuthenticationException, IOException, ServletException
40    {
41        Entitlements creds = new ObjectMapper().readValue(req.getInputStream(), Entitlements.class);

        return getAuthenticationManager().authenticate(
                new UsernamePasswordAuthenticationToken(creds.getId(), "", Collections.emptyList()));
    }
    //...
}

request objects get highlighted in checkmarx tool -

How do I properly validate, filter, escape, and/or encode user-controllable input to pass a Checkmarx scan?

5

There are 5 answers

0
StackOverFlow On BEST ANSWER

This worked for me - checkmarx pass this high vulnerability

I used combination of @reflexdemon ans and @tgdavies comment

@Override
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
        throws IOException
{
    int len = req.getContentLength();
    len = Integer.parseInt(Encode.forHtml(String.valueOf(len)));
    String type = req.getContentType();
    type =  Encode.forHtml(type);
    Entitlements creds;
    if(len == INPUT_LENGTH && type.equals(MIMETYPE_TEXT_PLAIN_UTF_8)) {
        creds = new ObjectMapper().readValue(req.getReader().lines().collect(Collectors.joining(System.lineSeparator())), Entitlements.class);
    }else{
        creds = new Entitlements();
    }

    return getAuthenticationManager().authenticate(
            new UsernamePasswordAuthenticationToken(creds.getId(), "", Collections.emptyList()));
}
0
yaloner On

Seems like the scanner found an XSS vulnerability in your code.

From OWASP's Cross-site Scripting (XSS) page:

Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user. Flaws that allow these attacks to succeed are quite widespread and occur anywhere a web application uses input from a user within the output it generates without validating or encoding it.

To learn in-depth how to avoid Cross-site Scripting vulnerabilities, it is very recommended to go over OWASP's XSS (Cross-Site Scripting) Prevention Cheat Sheet page. There are some sanitizer options listed there, and you can choose according to the specific language and relevant use.

Good luck.

7
reflexdemon On

Sometimes, we can trick the tool with a level of indirection. Can you try the below and see if that fixes your problem,

Replace:

Entitlements creds = new ObjectMapper().readValue(req.getInputStream(), Entitlements.class);

With,

Entitlements creds = new ObjectMapper().readValue(req.getReader().lines().collect(Collectors.joining(System.lineSeparator())), Entitlements.class);
0
Happy Young On

You code can be refactored to be like this:

// Negative
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {

    public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
            throws AuthenticationException, IOException, ServletException {

        if (req.getContentLength() > MAX_REQUEST_SIZE) {
            throw new IOException("request body size too big!");
        }

        Entitlements creds = new ObjectMapper().readValue(req.getInputStream(), Entitlements.class);

        return getAuthenticationManager()
                .authenticate(new UsernamePasswordAuthenticationToken(creds.getId(), "", Collections.emptyList()));
    }

}

You can use use getContentLength as a validator. While by default CxSAST 9.3 is not able to detect this validator. You can override the Java_Low_Visibility/Unrestricted_File_Upload query by the content from this file: https://github.com/checkmarx-ts/CxQL/blob/master/Java/Java_Low_Visibility/Unrestricted_File_Upload.txt

Other validators are also supported, getSize, getFileSize. You can also use MultipartConfig annotation with maxRequestSize. Or use multipart-config max-request-size in web.xml.

0
Loki On

Below solutions worked for me for checkmarx scan. In case of stored xss I used HtmlUtils.escapeHtmlContent(String)

In case if we want to sanitize the bean classes used in @requestbody we have to use

Jsoup.clean(StringEscapeUtils.escapHtml4(objectMapper.writeValueAsString(object)), Whitelist.basic());

This has solved the checkmarx vulnerability issues for me