Search code examples
javaxssveracode

Cross scripting error on the Retrieved Database data


I see a Cross Scripting injection error on the statement that follows the execute update. How do I sanitize the output to rid it of Cross scripting errors.. I have a simple code snippet which uses PreparedStatement to run a select and returns the values which is retrieved on the front end GUI screen.

XSS Flaw message:"The tainted data originated from an earlier call to java.sql.ResultSetMetaData.getColumnName. "

Java code:

        Connection conn = null;
        Statement stmt = null;
        PreparedStatement pstmt = null;
        try {
            List alist= new ArrayList();
            pstmt = conn.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery();
            int count = rs.getMetaData().getColumnCount();
            for (int i = 1; i <= count; i++) {
                 alist.add(rs.getMetaData().getColumnName(i))   //Flaw seems to point to this.
            }

        }catch(Exception e){
        //close connections
        }
        return alist;

Full Veracode Flaw: Attack Vector: javax.servlet.jsp.JspWriter.print

Number of Modules Affected: 1

Description: This call to javax.servlet.jsp.JspWriter.print() contains a cross-site scripting (XSS) flaw. The application populates the HTTP response with untrusted input, allowing an attacker to embed malicious content, such as Javascript code, which will be executed in the context of the victim's browser. XSS vulnerabilities are commonly exploited to steal or manipulate cookies, modify presentation of content, and compromise confidential information, with new attack vectors being discovered on a regular basis. The first argument to print() contains tainted data from the variable getHtml(). The tainted data originated from an earlier call to java.sql.ResultSetMetaData.getColumnName. The tainted data is directed into an output stream returned by javax.servlet.jsp.JspWriter.


Solution

  • So, I was finally able to figure out the problem.

    My Query was:

    SELECT COLUMN_A, COLUMN_A||'-'||COLUMN_B FROM SOME_TABLE WHERE COLUMN_C IS NULL;
    

    There are a few things I did...

    1) Add an alias name to my column and used rs.getMetaData().getcolumnlabel(i) instead of rs.getMetaData().getColumnName(i). This makes sure to eliminate pipeline or hyphens from the output resultset name.

    2) Used OWASP's ESAPI.encoder().encodeForHTML(unsafeString) instead of using Encode.forHtml(escapeHtml) and StringEscapeUtils.escapeHtml(escapeHtml) on the variable passed to the prepared statement.

    Ouput behavior of || and - when passing them through the various escape functions. Input: String unsafeString ="<'HELLO'-||>";

    Outputs:

    Encode.forHtml(unsafeString) is &lt;&#39;HELLO&#39;-||&gt; StringEscapeUtils.escapeHtml(unsafeString) is &lt;'HELLO'-||&gt; ESAPI.encoder().encodeForHTML(unsafeString) is &lt;&#x27;HELLO&#x27;-&#x7c;&#x7c;&gt; ESAPI.encoder().decodeForHTML(safeString from above line) is <'HELLO'-||>

    If the Output is sent to the jsp to be rendered back on the html then you dont have to do the decodeStep..