CWE-917, Improper Neutralization of Special Elements used in an Expression Language Statement, known as Expression Language Injection, applies when a product builds all or part of an expression language (EL) statement in a framework such as Java Server Pages, using externally influenced input, and does not neutralize special elements that could change the statement before it runs. MITRE lists Java as the platform.
If you run Java web applications or libraries that interpolate strings, this is relevant.
How it happens
Frameworks like JSP let developers put executable expressions inside otherwise static content. When developers do not realize those expressions execute, or do not turn them off, an attacker who can inject an expression can cause code execution or other unexpected behavior.
A simplified sketch of the pattern:
// Vulnerable: user input is placed inside an expression string
String expr = "#{user." + request.getParameter("field") + "}";
Object value = expressionFactory
.createValueExpression(elContext, expr, Object.class)
.getValue(elContext);
The attacker supplies field content that closes the property access and adds their own expression. The framework evaluates it with the application's privileges.
The headline example in the record is CVE-2021-44228 (details), the Log4Shell vulnerability in log4j. MITRE describes it as a product that does not neutralize dollar sign and brace style expressions, allowing remote code execution. A logging call that merely recorded attacker controlled text was enough, because the logging library interpreted special syntax inside the message.
${prefix:value}
That is the shape of the syntax in question. Any text that reaches the evaluator in this form is treated as an instruction. The lesson is that you do not need to write an expression to be exposed. A library you depend on may evaluate strings you pass it.
What an attacker gains
MITRE lists confidentiality, because application data can be read, and integrity, because unauthorized code or commands can be executed. Remote code execution means the attacker acts with the service's rights: reading secrets from memory and the environment, reaching internal systems, and changing data.
How to find it
MITRE notes automated static analysis (SAST) can find some instances by tracing data flow from sources of input to sinks, with high effectiveness. For EL injection the sink is the call that evaluates an expression string.
For the library angle, static analysis of your own code is not enough. You also need to know which dependencies you ship and which versions. A software composition scan lists them and matches them against known vulnerabilities. The free in-browser scan at gold.safeguard.sh/scan needs no login, keeps the file on your machine, and covers up to 100 dependencies. Reachability analysis then shows whether your code actually calls the vulnerable function, so the findings can be ordered by real exposure.
How to fix it
From MITRE:
- In design, avoid adding user controlled data to an expression interpreter when possible.
- If you must, do one or more of these: validate that the input will not evaluate as an expression, or encode it so it will not be evaluated as one.
- In system configuration and operation, use framework settings that disable processing of EL expressions. MITRE gives the example of setting the isELIgnored attribute of a JSP page to true.
Additional practice that follows from the Log4Shell case: keep libraries that interpolate strings up to date, and know where they sit in your dependency tree, including transitive ones.
Fixed sketch for the earlier code:
// Fixed: user input selects from a fixed list, never forms the expression
Set<String> allowed = Set.of("name", "email");
String field = request.getParameter("field");
if (!allowed.contains(field)) { throw new IllegalArgumentException(); }
Object value = user.get(field);
Try it yourself
The demo shows how a dependency inventory surfaces a vulnerable logging library and what to do next.
Click through it at your own pace, or open it full screen.
Quick check
What does isELIgnored do?
Setting it to true on a JSP page tells the framework not to process EL expressions on that page.
How can a logging library cause expression injection?
If it interprets special expression syntax inside logged text, attacker controlled input in a log message gets evaluated. That is the Log4Shell pattern in CVE-2021-44228.
Is input validation enough?
It is one of the options MITRE lists. Avoiding user data in the interpreter at all is listed first and is the stronger choice.