Skip to content

Expression Language (EL) Injection

Expression Language (EL) Injection

Description

Expression Language Injection (EL Injection) is a critical vulnerability arising from the mishandling of user inputs within expression languages commonly utilized in web applications. These languages serve to dynamically access and modify data. Attackers exploit EL Injection by injecting malicious code into these expressions. This unauthorized tampering can result in severe consequences, including unauthorized access, data breaches, or even the execution of remote code.

EL Injection primarily manifests within frameworks or templates supporting expression languages like JSP (JavaServer Pages), JSF (JavaServer Faces), Apache Struts, Thymeleaf, and various others commonly employed in web application development.

Example

  @RestController
  public class MathExpressionController {

      private final ExpressionParser parser = new SpelExpressionParser();

      @GetMapping("/evaluate")
      public String evaluateExpression(@RequestParam String expression) {
          Expression exp = parser.parseExpression(expression);
          try {
              Object result = exp.getValue();
              return "Result: " + result.toString();
          } catch (Exception e) {
              return "Error: Invalid expression";
          }
      }

  }

Recommendation

To secure the application against Expression Language Injection (EL Injection), consider the following recommendations:

  • Avoid Direct User Input Use: Whenever possible, avoid directly using user inputs in EL expressions. Instead, prefer a whitelist approach where only predefined, safe values are allowed to be used in EL expressions.

  • Input Validation: Validate and sanitize user inputs before using them in EL expressions. Implement strict validation to accept only expected data types and patterns.

  • Context-Specific Encoding: Use encoding functions provided by your framework or libraries (e.g., \ in JSP, fn:escapeXml() in JSTL) to ensure context-aware output encoding. This prevents the interpretation of user inputs as code.

Example

  @RestController
  public class MathExpressionController {

      private final ExpressionParser parser = new SpelExpressionParser();

      @GetMapping("/evaluate")
      public String evaluateExpression(@RequestParam String expression) {
          String sanitizedExpression = sanitizeInput(expression);
          Expression exp = parser.parseExpression(sanitizedExpression);
          try {
              Object result = exp.getValue();
              return "Result: " + result.toString();
          } catch (Exception e) {
              return "Error: Invalid expression";
          }
      }

      private String sanitizeInput(String input) {
          // Implement your input sanitization logic here
          // For this example, allow only basic arithmetic operations and numbers
          input = input.replaceAll("[^0-9\\+\\-\\*/]", ""); // Allow only digits, +, -, *, /
          return input;
      }
  }

Standards

  • CWE_TOP_25:
    • CWE_20
  • GDPR:
    • ART_5
    • ART_32
  • PCI_STANDARDS:
    • REQ_6_2
    • REQ_6_3
    • REQ_11_3
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_3_4
    • CC_4_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5