Skip to main content

DOM-Based cross-site scripting (XSS)

Need

Prevention of client-side execution of malicious scripts

Context

  • Usage of Java for building cross-platform applications and software solutions
  • Usage of javax.servlet for building Java web applications with Servlet technology
  • Usage of javax.servlet.http for handling HTTP requests and responses in Java Servlet applications

Description

Non compliant code

import javax.servlet.*;
import javax.servlet.http.*;

public class VulnerableServlet extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1> Hello, " + name + "!</h1>");
out.println("</body></html>");
}
}

The above Java code is an example of a vulnerable Servlet in a web application that is susceptible to DOM-based Cross-Site Scripting (XSS).

The doGet method in the VulnerableServlet class retrieves a parameter "name" from the HTTP request without any sanitization or encoding. This parameter is then directly embedded into the HTML response body that is sent to the client's browser.

Here's how the vulnerability can be exploited:

  1. An attacker can craft a URL with a script in the "name" parameter. For example: http://vulnerableapp.com/VulnerableServlet?name=<script>malicious_code_here</script>

  2. When a victim visits this URL, the malicious script is executed in their browser. Since the script is included in the HTML response from the server, the browser has no way of knowing that the script is not part of the legitimate web page.

This allows an attacker to perform actions on behalf of the victim, steal sensitive information like session cookies or personal data, or even deliver malware to the victim's machine.

Steps

  • Validate and sanitize user input: Before using any user input in the generated web content, validate and sanitize it to ensure it does not contain any malicious code.
  • Use output encoding: Encode user input before including it in the generated web content to prevent it from being interpreted as HTML or JavaScript code.
  • Implement a Content Security Policy (CSP): Use a Content Security Policy to restrict the types of content that can be loaded and executed on the web page, including scripts.
  • Implement strict input validation: Validate user input against a whitelist of allowed characters and reject any input that does not match the expected format.
  • Implement input validation on the server-side: Validate user input on the server-side to prevent malicious input from being processed and displayed on the client-side.
  • Implement proper error handling: Handle errors gracefully and avoid displaying sensitive information in error messages that could be exploited by attackers.
  • Regularly update and patch dependencies: Keep all software dependencies up to date and apply security patches to address any known vulnerabilities.
  • Implement secure coding practices: Follow secure coding practices to minimize the risk of introducing vulnerabilities in the code.
  • Educate developers: Provide training and education to developers on secure coding practices and common vulnerabilities to prevent similar issues in the future.

Compliant code

import javax.servlet.*;
import javax.servlet.http.*;
import org.owasp.encoder.Encode;

public class SecureServlet extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");

// Validate and sanitize user input
if (name == null || !name.matches("[A-Za-z0-9_]+")) {
throw new ServletException("Invalid input");
}

// Use output encoding
String safeName = Encode.forHtml(name);

PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1> Hello, " + safeName + "!</h1>");
out.println("</body></html>");
}
}

The updated code includes several measures to prevent DOM-Based Cross-Site Scripting (XSS) attacks:

  1. Input Validation: The user input is validated against a regular expression that only allows alphanumeric characters and underscores. If the input does not match this pattern, a ServletException is thrown. This prevents the injection of malicious scripts through the 'name' parameter.

  2. Output Encoding: The user input is encoded using the OWASP Java Encoder library before it is included in the generated HTML. This ensures that any special characters in the input are properly escaped and cannot be interpreted as HTML or JavaScript code.

  3. Error Handling: If the input validation fails, a ServletException is thrown. This prevents the application from processing and displaying potentially malicious input.

  4. Secure Coding Practices: The code follows secure coding practices by validating and sanitizing user input, using output encoding, and handling errors gracefully.

Please note that this code does not implement a Content Security Policy (CSP). CSP is a web standard that is implemented on the server side and cannot be demonstrated in this servlet code. However, it is highly recommended to implement a CSP in your web application to further mitigate the risk of XSS attacks.

References