Prevention of persistent cross-site scripting (XSS) attacks
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class VulnerableServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userComment = request.getParameter("comment");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("");
out.println("User Comment
");
out.println("" + userComment + "
"); // vulnerable line
out.println("");
}
}
The above servlet is vulnerable to Stored Cross-Site Scripting (XSS) attacks. This vulnerability arises from the fact that the servlet takes user input from the "comment" parameter and directly includes it in the HTML response without any sanitization or encoding.
In the
doPost
method, the
request.getParameter("comment")
is used to get the user input from the request. This user input is directly injected into the HTML response using
out.println("
" + userComment + "
"). This line of code is vulnerable because it does not sanitize or encode the user input before including it in the HTML response.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import org.owasp.encoder.Encode;
public class FixedServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userComment = request.getParameter("comment");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("");
out.println("User Comment
");
String safeUserComment = Encode.forHtml(userComment);
out.println("" + safeUserComment + "
"); // fixed line
out.println("");
}
}
The above code fixes the Stored Cross-Site Scripting (XSS) vulnerability by sanitizing the user input before it is displayed on the web page.
The user's comment is retrieved from the request parameter as before, but now it is passed through the
Encode.forHtml()
method from the OWASP Java Encoder library. This method encodes special characters that have significance in HTML to their corresponding HTML entities, effectively preventing them from being interpreted as code.
For example, the less-than character
<
would be encoded as
<
, the greater-than character
>
would be encoded as
>
, and so on. This way, even if the user's comment contains potentially malicious JavaScript code, it will be displayed as plain text on the web page, rather than being executed as code.
This fix assumes that the OWASP Java Encoder library is available in the classpath. If it's not, it can be added as a dependency in the project's build file. For Maven, the dependency would look like this:
<dependency>
<groupId>org.owasp.encoder</groupId>
<artifactId>encoder</artifactId>
<version>1.2.2</version>
</dependency>