Search code examples
javasecurityjspxsscheckmarx

How to solve this XSS security issue in JSP page


We have an very old web server with some JSP pages like below. I think I have checked the input parameter "version" with a whitelist "[a-zA-Z0-9]*". But the CheckMarx still got XSS attach warning: "This untrusted data is embedded straight into the output without proper sanitization or encoding, enabling an attacker to inject malicious code into the output.". Do you know how to do this correctly in JSP pages ? It just used to display something from the parameter input.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@page import="com.mytest.util.SecurityService"%>
<html>
<%
    String version = SecurityService.getSafeContent(request.getParameter("version"));
%>

<head>
<title>My Project</title>
</head>
<body>
    <div style="text-align: center">
        <table>
            <tr>
                <td>
                    <div style="text-align: center"><%=version%></div>
                </td>
            </tr>
        </table>
    </div>
</body>
</html>
public class SecurityService{
    public static final String PARAM_INVALID_DATA_POINT = "";
    
    public static String getSafeContent(String content) {
        if(!StringUtils.isEmpty(content) && content.matches("[a-zA-Z0-9]*")) {
            return content;
        }
        return PARAM_INVALID_DATA_POINT;
    }
}

Thanks,


Solution

  • It is because you are doing validation instead of sanitization. Validation is control flow type of approach for checking for vulnerable data (if not valid then...else...). Checkmarx SAST does data flow analysis but not control flow analysis.

    While today you could mark it false positive, someone could come in and refactor the code and perhaps inadvertently change your validation regex. Since it is marked false positive, it is possible the broken validation won't be caught. This is a simple regex, but think what might happen if it were a more complicated regex in addition to other validation logic.

    If you use something like the ESAPI encoder, it takes your potentially vulnerable input, changes it into a sanitized form, then returns the sanitized form. This would put the ESAPI encoder into the data flow, and should cause the result to be removed. Checkmarx SAST looks for sanitizers on the data flow path and, if a sanitizer is found, the data flow path is not reported as vulnerable.

    So you would have code like:

    <%
        String version = ESAPI.encoder().encodeForHTML(request.getParameter("version"));
    %>
    

    There are other encoder options, you'd just have to make sure they are recognized in your version of Checkmarx SAST.