VYPR
High severityNVD Advisory· Published Jan 10, 2022· Updated Apr 23, 2025

Sandbox Escape by math function in smarty

CVE-2021-29454

Description

Smarty template engine versions prior to 3.1.42 and 4.0.2 allow arbitrary PHP code execution through crafted math strings.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Smarty template engine versions prior to 3.1.42 and 4.0.2 allow arbitrary PHP code execution through crafted math strings.

Vulnerability

CVE-2021-29454 affects Smarty, a PHP template engine, versions prior to 3.1.42 and 4.0.2. The math function does not properly sanitize user-supplied math strings, allowing template authors or external users who can pass data to this function to inject arbitrary PHP code. The vulnerability exists in the smarty_function_math function, which evaluates mathematical expressions [1].

Exploitation

An attacker needs the ability to pass a malicious math string as user-provided data to the math function. No authentication is required if the function is exposed to user input. The attacker crafts a string containing PHP code disguised as mathematical operators, bypassing initial checks. The code is then executed within eval(), leading to arbitrary code execution [2].

Impact

Successful exploitation allows an attacker to execute arbitrary PHP code on the server with the privileges of the web application. This can lead to full compromise of the application and underlying system, including data theft, modification, or destruction [3].

Mitigation

Users should upgrade to Smarty version 3.1.42 or 4.0.2, which include input validation and restrict allowed functions in math expressions [4]. The commit 215d81a adds regex-based sanitization and disallows dangerous characters like backticks and dollar signs [2]. No workaround is available for older versions.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
smarty/smartyPackagist
< 3.1.423.1.42
smarty/smartyPackagist
>= 4.0.0, < 4.0.24.0.2

Affected products

2

Patches

1
215d81a9fa3c

Merge pull request from GHSA-29gp-2c3m-3j6m

https://github.com/smarty-php/smartySimon WisselinkJan 9, 2022via ghsa
3 files changed · +65 1
  • CHANGELOG.md+3 0 modified
    @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
     
     ## [Unreleased]
     
    +### Security
    +- Prevent arbitrary PHP code execution through maliciously crafted expression for the math function. This addresses CVE-2021-29454
    +
     ## [4.0.1] - 2022-01-09
     
     ### Security
    
  • libs/plugins/function.math.php+31 1 modified
    @@ -28,7 +28,12 @@ function smarty_function_math($params, $template)
                 'int'   => true,
                 'abs'   => true,
                 'ceil'  => true,
    +            'acos'   => true,
    +            'acosh'   => true,
                 'cos'   => true,
    +            'cosh'   => true,
    +            'deg2rad'   => true,
    +            'rad2deg'   => true,
                 'exp'   => true,
                 'floor' => true,
                 'log'   => true,
    @@ -39,27 +44,51 @@ function smarty_function_math($params, $template)
                 'pow'   => true,
                 'rand'  => true,
                 'round' => true,
    +            'asin'   => true,
    +            'asinh'   => true,
                 'sin'   => true,
    +            'sinh'   => true,
                 'sqrt'  => true,
                 'srand' => true,
    -            'tan'   => true
    +            'atan'   => true,
    +            'atanh'   => true,
    +            'tan'   => true,
    +            'tanh'   => true
             );
    +
         // be sure equation parameter is present
         if (empty($params[ 'equation' ])) {
             trigger_error("math: missing equation parameter", E_USER_WARNING);
             return;
         }
         $equation = $params[ 'equation' ];
    +
    +    // Remove whitespaces
    +    $equation = preg_replace('/\s+/', '', $equation);
    +
    +    // Adapted from https://www.php.net/manual/en/function.eval.php#107377
    +    $number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number
    +    $functionsOrVars = '((?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))';
    +    $operators = '[+\/*\^%-]'; // Allowed math operators
    +    $regexp = '/^(('.$number.'|'.$functionsOrVars.'|('.$functionsOrVars.'\s*\((?1)+\)|\((?1)+\)))(?:'.$operators.'(?2))?)+$/';
    +
    +    if (!preg_match($regexp, $equation)) {
    +        trigger_error("math: illegal characters", E_USER_WARNING);
    +        return;
    +    }
    +
         // make sure parenthesis are balanced
         if (substr_count($equation, '(') !== substr_count($equation, ')')) {
             trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
             return;
         }
    +
         // disallow backticks
         if (strpos($equation, '`') !== false) {
             trigger_error("math: backtick character not allowed in equation", E_USER_WARNING);
             return;
         }
    +
         // also disallow dollar signs
         if (strpos($equation, '$') !== false) {
             trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING);
    @@ -96,6 +125,7 @@ function smarty_function_math($params, $template)
         }
         $smarty_math_result = null;
         eval("\$smarty_math_result = " . $equation . ";");
    +
         if (empty($params[ 'format' ])) {
             if (empty($params[ 'assign' ])) {
                 return $smarty_math_result;
    
  • tests/UnitTests/TemplateSource/ValueTests/Math/MathTest.php+31 0 modified
    @@ -107,4 +107,35 @@ public function testFunctionString()
             $tpl = $this->smarty->createTemplate('eval:{$x = "4"}{$y = "5.5"}{math equation="x * y" x=$x y=$y format="%0.2f"} -- {math equation="20.5 / 5" format="%0.2f"}');
             $this->assertEquals($expected, $this->smarty->fetch($tpl));
         }
    +
    +	/**
    +	 * @expectedException PHPUnit_Framework_Error_Warning
    +	 */
    +	public function testBackticksIllegal()
    +	{
    +		$expected = "22.00";
    +		$tpl = $this->smarty->createTemplate('eval:{$x = "4"}{$y = "5.5"}{math equation="`ls` x * y" x=$x y=$y}');
    +		$this->assertEquals($expected, $this->smarty->fetch($tpl));
    +	}
    +
    +	/**
    +	 * @expectedException PHPUnit_Framework_Error_Warning
    +	 */
    +	public function testDollarSignsIllegal()
    +	{
    +		$expected = "22.00";
    +		$tpl = $this->smarty->createTemplate('eval:{$x = "4"}{$y = "5.5"}{math equation="$" x=$x y=$y}');
    +		$this->assertEquals($expected, $this->smarty->fetch($tpl));
    +	}
    +
    +	/**
    +	 * @expectedException PHPUnit_Framework_Error_Warning
    +	 */
    +	public function testBracketsIllegal()
    +	{
    +		$expected = "I";
    +		$tpl = $this->smarty->createTemplate('eval:{$x = "0"}{$y = "1"}{math equation="((y/x).(x))[x]" x=$x y=$y}');
    +		$this->assertEquals($expected, $this->smarty->fetch($tpl));
    +	}
    +
     }
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

16

News mentions

0

No linked articles in our index yet.