The vulnerability lies in the simpleeval library's failure to properly sanitize the objects returned during the evaluation of an expression. The root cause is in the SimpleEval._eval method. Before the patch, this method would evaluate a part of the expression (a node) and return the resulting object without any security checks. This allowed an attacker to craft an expression that, when evaluated, would return a reference to a Python module (like os) or a dangerous function that was inadvertently passed into the sandbox environment via the names dictionary. The returned object could then be used to perform malicious actions. The patch introduces a new function, _check_disallowed_items, which recursively inspects objects for modules and forbidden functions. This check is now called within _eval on the result of every node evaluation, effectively closing the vulnerability by preventing dangerous objects from being leaked back to the expression evaluator.