Skip to content

Commit 215d81a

Browse files
authored
Merge pull request from GHSA-29gp-2c3m-3j6m
* Temporary fix. Waiting for CVE * Add CVE
1 parent efb416e commit 215d81a

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

Diff for: CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
### Security
10+
- Prevent arbitrary PHP code execution through maliciously crafted expression for the math function. This addresses CVE-2021-29454
11+
912
## [4.0.1] - 2022-01-09
1013

1114
### Security

Diff for: libs/plugins/function.math.php

+31-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@ function smarty_function_math($params, $template)
2828
'int' => true,
2929
'abs' => true,
3030
'ceil' => true,
31+
'acos' => true,
32+
'acosh' => true,
3133
'cos' => true,
34+
'cosh' => true,
35+
'deg2rad' => true,
36+
'rad2deg' => true,
3237
'exp' => true,
3338
'floor' => true,
3439
'log' => true,
@@ -39,27 +44,51 @@ function smarty_function_math($params, $template)
3944
'pow' => true,
4045
'rand' => true,
4146
'round' => true,
47+
'asin' => true,
48+
'asinh' => true,
4249
'sin' => true,
50+
'sinh' => true,
4351
'sqrt' => true,
4452
'srand' => true,
45-
'tan' => true
53+
'atan' => true,
54+
'atanh' => true,
55+
'tan' => true,
56+
'tanh' => true
4657
);
58+
4759
// be sure equation parameter is present
4860
if (empty($params[ 'equation' ])) {
4961
trigger_error("math: missing equation parameter", E_USER_WARNING);
5062
return;
5163
}
5264
$equation = $params[ 'equation' ];
65+
66+
// Remove whitespaces
67+
$equation = preg_replace('/\s+/', '', $equation);
68+
69+
// Adapted from https://www.php.net/manual/en/function.eval.php#107377
70+
$number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number
71+
$functionsOrVars = '((?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))';
72+
$operators = '[+\/*\^%-]'; // Allowed math operators
73+
$regexp = '/^(('.$number.'|'.$functionsOrVars.'|('.$functionsOrVars.'\s*\((?1)+\)|\((?1)+\)))(?:'.$operators.'(?2))?)+$/';
74+
75+
if (!preg_match($regexp, $equation)) {
76+
trigger_error("math: illegal characters", E_USER_WARNING);
77+
return;
78+
}
79+
5380
// make sure parenthesis are balanced
5481
if (substr_count($equation, '(') !== substr_count($equation, ')')) {
5582
trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
5683
return;
5784
}
85+
5886
// disallow backticks
5987
if (strpos($equation, '`') !== false) {
6088
trigger_error("math: backtick character not allowed in equation", E_USER_WARNING);
6189
return;
6290
}
91+
6392
// also disallow dollar signs
6493
if (strpos($equation, '$') !== false) {
6594
trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING);
@@ -96,6 +125,7 @@ function smarty_function_math($params, $template)
96125
}
97126
$smarty_math_result = null;
98127
eval("\$smarty_math_result = " . $equation . ";");
128+
99129
if (empty($params[ 'format' ])) {
100130
if (empty($params[ 'assign' ])) {
101131
return $smarty_math_result;

Diff for: tests/UnitTests/TemplateSource/ValueTests/Math/MathTest.php

+31
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,35 @@ public function testFunctionString()
107107
$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"}');
108108
$this->assertEquals($expected, $this->smarty->fetch($tpl));
109109
}
110+
111+
/**
112+
* @expectedException PHPUnit_Framework_Error_Warning
113+
*/
114+
public function testBackticksIllegal()
115+
{
116+
$expected = "22.00";
117+
$tpl = $this->smarty->createTemplate('eval:{$x = "4"}{$y = "5.5"}{math equation="`ls` x * y" x=$x y=$y}');
118+
$this->assertEquals($expected, $this->smarty->fetch($tpl));
119+
}
120+
121+
/**
122+
* @expectedException PHPUnit_Framework_Error_Warning
123+
*/
124+
public function testDollarSignsIllegal()
125+
{
126+
$expected = "22.00";
127+
$tpl = $this->smarty->createTemplate('eval:{$x = "4"}{$y = "5.5"}{math equation="$" x=$x y=$y}');
128+
$this->assertEquals($expected, $this->smarty->fetch($tpl));
129+
}
130+
131+
/**
132+
* @expectedException PHPUnit_Framework_Error_Warning
133+
*/
134+
public function testBracketsIllegal()
135+
{
136+
$expected = "I";
137+
$tpl = $this->smarty->createTemplate('eval:{$x = "0"}{$y = "1"}{math equation="((y/x).(x))[x]" x=$x y=$y}');
138+
$this->assertEquals($expected, $this->smarty->fetch($tpl));
139+
}
140+
110141
}

0 commit comments

Comments
 (0)