Affected versions
Symfony Expression Language versions <5.4.54, >=6, <6.4.48, >=7, <7.4.21, >=8, <8.1.9 are affected by this security issue.
The issue has been fixed in Symfony Expression Language 5.4.54, 6.4.48, 7.4.21, 8.1.9.
Description
The parser of the ExpressionLanguage component built its node tree with no bound on its depth. An expression made of tens of thousands of nested unary operators, array literals, binary operators or property accesses crashed the PHP process, while the tree was being freed.
#[Assert\ExpressionSyntax] passes the validated value to ExpressionLanguage::lint(), so an application validating expressions written by its users could be crashed by a single request, and so could any code parsing untrusted expressions.
Resolution
The parser now counts the nodes stacked on the branch it is building, including the shapes that fold iteratively rather than recursively, and raises a SyntaxError beyond 256 levels, which callers already handle as an invalid expression.
The first release of this fix, in 6.4.45, 7.4.18 and 8.1.6, missed the levels that a chain of binary operators or of property accesses adds above its first operand. With 60 levels of parentheses holding 60 additions each, as in ((1 + 1 + 1) + 1 + 1), the expression was still accepted, and serializing it for the default cache crashed the process. The parser now also checks the depth of the node tree once parsed. 6.4.48, 7.4.21 and 8.1.9 contain both changes.
The patches for this issue are available here for branch 5.4 (and forward-ported to 6.4, 7.4, 8.1 and 8.2).
The fix was made in #65690, with follow-ups in #66723 and in #66720 for chained ternaries.
Credits
We would like to thank Nicolas Grekas for providing the fix.