Checkmarx - 如何验证和清理 HttpServletRequest .getInputStream 以通过 checkmarx 扫描

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

以下是 checkmarx 问题的详细信息 无限制文件上传

源对象:请求(第 39 行)

目标对象:getInputStream(第 -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()));
    }
    //...
}

请求 对象在 checkmarx 工具中突出显示 -

如何正确验证、过滤、转义、and/or 编码用户可控输入以通过 Checkmarx 扫描?

扫描器似乎在您的代码中发现了 XSS 漏洞。

来自 OWASP 的 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.

要学习 in-depth 如何避免 Cross-site 脚本漏洞,非常推荐阅读 OWASP 的 XSS (Cross-Site Scripting) Prevention Cheat Sheet page。 上面列出了一些sanitizer选项,大家可以根据具体的语言和相关用途来选择。

祝你好运。

有时,我们可以通过间接级别来欺骗该工具。你能试试下面的方法,看看是否能解决你的问题,

替换:

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

有,

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

这对我有用 - checkmarx 通过了这个高漏洞

我使用了@reflexdemon ans 和@tgdavies 评论的组合

@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()));
}

你的代码可以重构成这样:

// 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()));
    }

}

您可以使用 getContentLength 作为验证器。虽然默认情况下 CxSAST 9.3 无法检测到此验证器。您可以通过此文件中的内容覆盖 Java_Low_Visibility/Unrestricted_File_Upload 查询: https://github.com/checkmarx-ts/CxQL/blob/master/Java/Java_Low_Visibility/Unrestricted_File_Upload.txt

还支持其他验证器,getSizegetFileSize。您还可以将 MultipartConfig 注释与 maxRequestSize 一起使用。或者在web.xml.

中使用multipart-configmax-request-size

以下解决方案适用于 checkmarx 扫描。 在存储 xss 的情况下,我使用 HtmlUtils.escapeHtmlContent(String)

如果我们想要清理 @requestbody 中使用的 bean 类,我们必须使用

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

这已经为我解决了 checkmarx 漏洞问题