Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a 'strict_callables' option to Mustache_Engine
Prevents treating array('ClassName', 'methodName') or array($instance, 'methodName') as section or interpolation callables. This helps protect against arbitrary code evaluation when user input is passed directly into the template. This setting is recommended for PHP 5.3+, and all PHP 5.2 projects not using section or interpolation lambdas. The default value is false to preserve backwards compatibility. See #138
- Loading branch information
Showing
3 changed files
with
206 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
147 changes: 147 additions & 0 deletions
147
test/Mustache/Test/FiveThree/Functional/StrictCallablesTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,147 @@ | |||
<?php | |||
|
|||
/* | |||
* This file is part of Mustache.php. | |||
* | |||
* (c) 2013 Justin Hileman | |||
* | |||
* For the full copyright and license information, please view the LICENSE | |||
* file that was distributed with this source code. | |||
*/ | |||
|
|||
/** | |||
* @group lambdas | |||
* @group functional | |||
*/ | |||
class Mustache_Test_FiveThree_Functional_StrictCallablesTest extends PHPUnit_Framework_TestCase | |||
{ | |||
/** | |||
* @dataProvider callables | |||
*/ | |||
public function testStrictCallablesDisabled($name, $section, $expected) | |||
{ | |||
$mustache = new Mustache_Engine(array('strict_callables' => false)); | |||
$tpl = $mustache->loadTemplate('{{# section }}{{ name }}{{/ section }}'); | |||
|
|||
$data = new StdClass; | |||
$data->name = $name; | |||
$data->section = $section; | |||
|
|||
$this->assertEquals($expected, $tpl->render($data)); | |||
} | |||
|
|||
public function callables() | |||
{ | |||
$lambda = function($tpl, $mustache) { | |||
return strtoupper($mustache->render($tpl)); | |||
}; | |||
|
|||
return array( | |||
// Interpolation lambdas | |||
array( | |||
array($this, 'instanceName'), | |||
$lambda, | |||
'YOSHI', | |||
), | |||
array( | |||
array(__CLASS__, 'staticName'), | |||
$lambda, | |||
'YOSHI', | |||
), | |||
array( | |||
function() { return 'Yoshi'; }, | |||
$lambda, | |||
'YOSHI', | |||
), | |||
|
|||
// Section lambdas | |||
array( | |||
'Yoshi', | |||
array($this, 'instanceCallable'), | |||
'YOSHI', | |||
), | |||
array( | |||
'Yoshi', | |||
array(__CLASS__, 'staticCallable'), | |||
'YOSHI', | |||
), | |||
array( | |||
'Yoshi', | |||
$lambda, | |||
'YOSHI', | |||
), | |||
); | |||
} | |||
|
|||
|
|||
/** | |||
* @group wip | |||
* @dataProvider strictCallables | |||
*/ | |||
public function testStrictCallablesEnabled($name, $section, $expected) | |||
{ | |||
$mustache = new Mustache_Engine(array('strict_callables' => true)); | |||
$tpl = $mustache->loadTemplate('{{# section }}{{ name }}{{/ section }}'); | |||
|
|||
$data = new StdClass; | |||
$data->name = $name; | |||
$data->section = $section; | |||
|
|||
$this->assertEquals($expected, $tpl->render($data)); | |||
} | |||
|
|||
public function strictCallables() | |||
{ | |||
$lambda = function($tpl, $mustache) { | |||
return strtoupper($mustache->render($tpl)); | |||
}; | |||
|
|||
return array( | |||
// Interpolation lambdas | |||
array( | |||
function() { return 'Yoshi'; }, | |||
$lambda, | |||
'YOSHI', | |||
), | |||
|
|||
// Section lambdas | |||
array( | |||
'Yoshi', | |||
array($this, 'instanceCallable'), | |||
'YoshiYoshi', | |||
), | |||
array( | |||
'Yoshi', | |||
array(__CLASS__, 'staticCallable'), | |||
'YoshiYoshi', | |||
), | |||
array( | |||
'Yoshi', | |||
function($tpl, $mustache) { | |||
return strtoupper($mustache->render($tpl)); | |||
}, | |||
'YOSHI', | |||
), | |||
); | |||
} | |||
|
|||
public function instanceCallable($tpl, $mustache) | |||
{ | |||
return strtoupper($mustache->render($tpl)); | |||
} | |||
|
|||
public static function staticCallable($tpl, $mustache) | |||
{ | |||
return strtoupper($mustache->render($tpl)); | |||
} | |||
|
|||
public function instanceName() | |||
{ | |||
return 'Yoshi'; | |||
} | |||
|
|||
public static function staticName() | |||
{ | |||
return 'Yoshi'; | |||
} | |||
} |