Description
The ExpressionLanguage component page (https://symfony.com/doc/current/components/expression_language.html) states:
“Expressions can be seen as a very restricted PHP sandbox and are immune to external injections as you must explicitly declare which variables are available in an expression.”
However, this statement is a bit misleading as expression injection is very possible when mapping tainted data to expression variables in the $values array. Even though an injected expression is limited to a predefined set of variables and operators, an attacker can still modify the expression and alter application logic. The documentation also states that the ExpressionLanguage component may be used for validation which further increases the likelihood that a developer will pass tainted data into the expression and create an expression injection vulnerability. I suggest updating the documentation at https://github.com/symfony/symfony-docs/blob/master/components/expression_language.rst to explicitly state that tainted data should not be passed to the $values array (or appended directly to the expression string).
To demonstrate the issue, consider the example code block below:
$user = $_GET['user'];
if(!$language->evaluate('user["username"] matches "/[a-zA-Z0-9]$/"', array("user" => $user))){
return new Response("Validation failed!");
}
Passing the following user parameter will alter the expression and bypass the validation:
<script>alert('XSS_SUCCESS!')</script>" > 0 | "a
I will try to update the documentation and submit a pull request as time permits.