Prevent XSS exploitTag(s): Security


According to Wikipedia, XSS exploit is a type of computer security vulnerability found in web applications which allow code injection by malicious web users into the web pages viewed by other users. If your WebApp expects a URL like http://www.server.com/app?name=John then a malicious user can build a special URL like http://www.server.com/app?name=<script> ... </script> to "inject" his own script into your web app.

This can be be very dangerous if the data is stored into a database and displayed to other users.

Good document on the subject : XSS (Cross Site Scripting) Prevention Cheat Sheet

Here a list of XSS test cases : http://ha.ckers.org/xss.html

There are three ways to deal with this issue.

Sanitize the input by removing suspicious tags.
This is a naive approach because it's almost impossible to cover everything.

This regex function removes the obvious code to inject unwanted scripting.

public static String sanitize(String string) {
  return string
     .replaceAll("(?i)<script.*?>.*?</script.*?>", "")   // case 1
     .replaceAll("(?i)<.*?javascript:.*?>.*?</.*?>", "") // case 2
     .replaceAll("(?i)<.*?\\s+on.*?>.*?</.*?>", "");     // case 3
}
  • (?i) make it case insensitive
  • case 1 : <script> are removed
  • case 2 : javascript: call are removed
  • case 3 : remove on* attributes like onLoad or onClick

    Nothing beats good validation but then make sure to sanitize the value if it fails before redisplaying it.

    While you can call yourself the method to sanitize the received parameters, you should consider installing this process into a Java EE filter so the container will automatically do it for you. See this page at http://greatwebguy.com/programming/java/simple-cross-site-scripting-xss-servlet-filter/.

    You have to be careful. You don't want to remove legitimate string. An input like "prescription" can be become "preion" if the filter is too strict!

    Sanitize the input based on a policy file.
    Based on a policy file, you allow only certain tags and discard everything else.

    See http://www.owasp.org/index.php/AntiSamy for a ready to use library.

    Sanitize the output by removing suspicious characters.
    The idea is to sanitize a string before displaying it a user. This is done by replacing supicious characters by the corresponding entity.

    The JSTL taglib provides the tag <c:out ... > tag to display a string. This tag will sanitize a string by default.

    <c:out value="${foo}" escapeXml="true" />
    

    The substitutions are :

    Character Entity Code
    < &lt;
    > &gt;
    & &amp;
    ' &#039;
    " &#034;

    This JSP will display the script code and the browser will not execute it.

    <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
    <c:set var="test" scope="session">
      <script>
        alert("hello")
      </script>
    </c:set>
    
    <h1>out with escapeXml=true</h1>
    <c:out value="${test}" escapeXml="true" /><br>
    <br />
    

    This JSP will not display the script code and the browser execute it.

    <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
    <c:set var="test" scope="session">
      <script>
        alert("hello")
      </script>
    </c:set>
    
    <h1>out with escapeXml=false</h1>
    <c:out value="${test}" escapeXml="false" /><br>
    <br />
    
    With JSF, the tag <h:outputtext ... > provides the same protection.

    Also see Java Edition of the OWASP ESAPI Toolkit


    blog comments powered by Disqus