Compare commits

..

13 Commits

Author SHA1 Message Date
Simon Wisselink e05dabf369 Fixed logic error in this changed if statement 2021-03-15 10:00:00 +01:00
Simon Wisselink 1eb2851c03 Take out one more stat call (on the compiled template) by not calculating it's existence / timestamp when compile_check is false. 2021-03-12 23:10:33 +01:00
Simon Wisselink a832410ef3 Optimize away one stat call per template request by optimistically assuming the source template exists. Note that this implementation disables support for the fallback to templates relative to getcwd() if a template is not found in the specified template dirs, so it might be better to release this as a new version, or to add an alternative resource for this. 2021-03-12 22:50:50 +01:00
Simon Wisselink e27da524f7 Merge branch 'release/3.1.39' 2021-02-17 22:57:51 +01:00
Simon Wisselink a21f59663c version bump 2021-02-17 22:57:50 +01:00
Simon Wisselink 3148d406a0 changelog 2021-02-17 22:57:33 +01:00
Simon Wisselink 4f634c0097 Merge branch 'bugfix/tplfunction_sandbox_escape' 2021-02-17 22:52:34 +01:00
Simon Wisselink c9272058d9 Merge branch 'bugfix/template_object_sandbox_escape' 2021-02-17 22:51:38 +01:00
Simon Wisselink e66e293a8a Do not push release automatically in make release script, to enable a chance to catch any errors. 2021-02-17 22:50:52 +01:00
Simon Wisselink 74cab5a56b updated changelog header to security 2021-02-17 22:30:35 +01:00
Simon Wisselink 8fc66e27a7 Cannot use in Smarty3 yet, revert to @expectedException 2021-02-01 10:33:00 +01:00
Simon Wisselink 288a54f6b0 Add unit test 2021-01-24 23:52:45 +01:00
Simon Wisselink 6463519a6c Prevent access to .template_object when in security mode to prevent PHP code injection vulnerability 2021-01-24 23:13:26 +01:00
8 changed files with 56 additions and 15 deletions
+4 -1
View File
@@ -6,8 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [3.1.39] - 2021-02-17
### Security
- Code injection vulnerability by using illegal function names in `{function name='blah'}{/function}`
- Prevent access to `$smarty.template_object` in sandbox mode
- Fixed code injection vulnerability by using illegal function names in `{function name='blah'}{/function}`
## [3.1.38] - 2021-01-08
View File
+1 -1
View File
@@ -111,7 +111,7 @@ class Smarty extends Smarty_Internal_TemplateBase
/**
* smarty version
*/
const SMARTY_VERSION = '3.1.38';
const SMARTY_VERSION = '3.1.39';
/**
* define variable scopes
*/
@@ -81,6 +81,10 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
case 'template':
return 'basename($_smarty_tpl->source->filepath)';
case 'template_object':
if (isset($compiler->smarty->security_policy)) {
$compiler->trigger_template_error("(secure mode) template_object not permitted");
break;
}
return '$_smarty_tpl';
case 'current_dir':
return 'dirname($_smarty_tpl->source->filepath)';
@@ -37,7 +37,8 @@ class Smarty_Internal_Resource_File extends Smarty_Resource
$source->filepath . ($source->isConfig ? $source->smarty->_joined_config_dir :
$source->smarty->_joined_template_dir)
);
$source->timestamp = filemtime($source->filepath);
// When not doing compile_check, set timestamp to true
$source->timestamp = $source->smarty->compile_check ? filemtime($source->filepath) : true;
} else {
$source->timestamp = $source->exists = false;
}
@@ -50,6 +51,10 @@ class Smarty_Internal_Resource_File extends Smarty_Resource
*/
public function populateTimestamp(Smarty_Template_Source $source)
{
if (!$source->smarty->compile_check) {
$source->timestamp = $source->exists = true;
return;
}
if (!$source->exists) {
$source->timestamp = $source->exists = is_file($source->filepath);
}
@@ -68,13 +73,15 @@ class Smarty_Internal_Resource_File extends Smarty_Resource
*/
public function getContent(Smarty_Template_Source $source)
{
if ($source->exists) {
return file_get_contents($source->filepath);
if (($source->smarty->compile_check && !$source->exists)
|| false === ($content = file_get_contents($source->filepath))
) {
throw new SmartyException(
'Unable to read ' . ($source->isConfig ? 'config' : 'template') .
" {$source->type} '{$source->name}'"
);
}
throw new SmartyException(
'Unable to read ' . ($source->isConfig ? 'config' : 'template') .
" {$source->type} '{$source->name}'"
);
return $content;
}
/**
@@ -126,6 +133,17 @@ class Smarty_Internal_Resource_File extends Smarty_Resource
$file = str_replace(DIRECTORY_SEPARATOR === '/' ? '\\' : '/', DIRECTORY_SEPARATOR, $file);
}
$_directories = $source->smarty->getTemplateDir(null, $source->isConfig);
// If possible, assume the file exists when compile_check = false;
if (!$source->smarty->compile_check
&& count($_directories) == 1 // if there are multiple directories, we'll have to scan them
&& $file[ 0 ] !== '[' // template_dir index
&& !$source->smarty->use_include_path // cannot optimize when we need to use include path
) {
$path = reset($_directories) . $file;
return (strpos($path, '.' . DIRECTORY_SEPARATOR) !== false) ? $source->smarty->_realpath($path) : $path;
}
// template_dir index?
if ($file[ 0 ] === '[' && preg_match('#^\[([^\]]+)\](.+)$#', $file, $fileMatch)) {
$file = $fileMatch[ 2 ];
@@ -157,6 +175,7 @@ class Smarty_Internal_Resource_File extends Smarty_Resource
$_directories = $_index_dirs;
}
}
// relative file name?
foreach ($_directories as $_directory) {
$path = $_directory . $file;
+11 -5
View File
@@ -74,9 +74,14 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
$this->filepath .= '.cache';
}
$this->filepath .= '.php';
$this->timestamp = $this->exists = is_file($this->filepath);
if ($this->exists) {
$this->timestamp = filemtime($this->filepath);
if ($smarty->compile_check) {
$this->timestamp = $this->exists = is_file($this->filepath);
if ($this->exists) {
$this->timestamp = filemtime($this->filepath);
}
} else {
$this->timestamp = $this->exists = true;
}
}
@@ -135,8 +140,9 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
if ($source->handler->recompiled) {
$source->handler->process($_smarty_tpl);
} elseif (!$source->handler->uncompiled) {
if (!$this->exists || $smarty->force_compile
|| ($_smarty_tpl->compile_check && $source->getTimeStamp() > $this->getTimeStamp())
if (
$smarty->force_compile ||
($_smarty_tpl->compile_check && (!$this->exists || ($source->getTimeStamp() > $this->getTimeStamp())))
) {
$this->compileTemplateSource($_smarty_tpl);
$compileCheck = $_smarty_tpl->compile_check;
+1 -1
View File
@@ -14,6 +14,6 @@ git pull
git merge --no-ff "release/$1"
git branch -d "release/$1"
git tag -a "v$1" -m "Release $1"
git push --follow-tags
printf 'Done creating release %s\n' "$1"
printf 'Run `git push --follow-tags origin` to publish it.\n'
@@ -382,6 +382,15 @@ class SecurityTest extends PHPUnit_Smarty
$this->smarty->security_policy->trusted_uri = array();
$this->assertContains('<title>Preface | Smarty</title>', $this->smarty->fetch('string:{fetch file="https://www.smarty.net/docs/en/preface.tpl"}'));
}
/**
* In security mode, accessing $smarty.template_object should be illegal.
* @expectedException SmartyCompilerException
*/
public function testSmartyTemplateObject() {
$this->smarty->display('string:{$smarty.template_object}');
}
}
class mysecuritystaticclass