- bugfix any tag placed within "<script language=php>" will throw a security exception to close all thinkable holes

This commit is contained in:
Uwe.Tews@googlemail.com
2014-10-14 21:45:05 +00:00
parent 4dde85a089
commit c77cc80a8c
4 changed files with 328 additions and 329 deletions

View File

@@ -1,4 +1,7 @@
===== 3.1.21-dev ===== (xx.xx.2014)
14.10.2014
- bugfix any tag placed within "<script language=php>" will throw a security exception to close all thinkable holes
12.10.2014
- bugfix a comment like "<script{*foo*} language=php>" bypassed $php_handling checking (Thue Kristensen)
- bugfix change of 08.10.2014 could create E_NOTICE meassage when using "<?php" tags

View File

@@ -245,7 +245,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
// loop over items, stitch back together
foreach ($cache_split as $curr_idx => $curr_split) {
// escape PHP tags in template content
$output .= preg_replace('/(<%|%>|<\?php|<\?|\?>)/', "<?php echo '\$1'; ?>\n", $curr_split);
$output .= preg_replace('/(<%|%>|<\?php|<\?|\?>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>)/', "<?php echo '\$1'; ?>\n", $curr_split);
if (isset($cache_parts[0][$curr_idx])) {
$_template->properties['has_nocache_code'] = true;
// remove nocache tags from cache output

View File

@@ -21,7 +21,6 @@ class Smarty_Internal_Templatelexer
public $line;
public $taglineno;
public $is_phpScript = false;
public $phpValue = '';
public $state = 1;
public $smarty;
private $heredoc_id_stack = Array();
@@ -164,14 +163,13 @@ class Smarty_Internal_Templatelexer
19 => 0,
20 => 0,
21 => 0,
22 => 0,
23 => 4,
28 => 0,
22 => 4,
27 => 0,
);
if ($this->counter >= strlen($this->data)) {
return false; // end of input
}
$yy_global_pattern = "/\G(\\{\\})|\G(" . $this->ldel . "\\*([\S\s]*?)\\*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*strip\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*\/strip\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*literal\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*(if|elseif|else if|while)\\s+)|\G(" . $this->ldel . "\\s*for\\s+)|\G(" . $this->ldel . "\\s*foreach(?![^\s]))|\G(" . $this->ldel . "\\s*setfilter\\s+)|\G(" . $this->ldel . "\\s*\/)|\G(" . $this->ldel . "\\s*)|\G((<script\\s+language\\s*=\\s*[\"']?\\s*php\\s*[\"']?\\s*>)|(<\\?(?:php\\w+|=|[a-zA-Z]+)?))|\G(\\?>)|\G(<\/script>)|\G(<\/script>)|\G(\\s*" . $this->rdel . ")|\G(<%)|\G(%>)|\G(<(([^>]*?)(?=" . $this->ldel . ")" . $this->ldel . "\\*([\S\s]*?)\\*" . $this->rdel . ")+([^>]*?)(?!" . $this->ldel . ")>)|\G([\S\s])/iS";
$yy_global_pattern = "/\G(\\{\\})|\G(" . $this->ldel . "\\*([\S\s]*?)\\*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*strip\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*\/strip\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*literal\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*(if|elseif|else if|while)\\s+)|\G(" . $this->ldel . "\\s*for\\s+)|\G(" . $this->ldel . "\\s*foreach(?![^\s]))|\G(" . $this->ldel . "\\s*setfilter\\s+)|\G(" . $this->ldel . "\\s*\/)|\G(" . $this->ldel . "\\s*)|\G((<script\\s+language\\s*=\\s*[\"']?\\s*php\\s*[\"']?\\s*>)|(<\\?(?:php\\w+|=|[a-zA-Z]+)?))|\G(\\?>)|\G(<\/script>)|\G(\\s*" . $this->rdel . ")|\G(<%)|\G(%>)|\G(<(([^>]*?)(?=" . $this->ldel . ")" . $this->ldel . "([\S\s]*?)" . $this->rdel . ")+([^>]*?)(?!" . $this->ldel . ")>)|\G([\S\s])/iS";
do {
if (preg_match($yy_global_pattern, $this->data, $yymatches, null, $this->counter)) {
@@ -339,11 +337,10 @@ class Smarty_Internal_Templatelexer
function yy_r1_14($yy_subpatterns)
{
if ($script = strpos($this->value, '<s') === 0 || in_array($this->value, Array('<?', '<?=', '<?php'))) {
if (($script = strpos($this->value, '<s') === 0) || in_array($this->value, Array('<?', '<?=', '<?php'))) {
if ($script) {
$this->is_phpScript = true;
}
$this->phpValue = $this->value;
$this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG;
} elseif ($this->value == '<?xml') {
$this->token = Smarty_Internal_Templateparser::TP_XMLTAG;
@@ -368,35 +365,27 @@ class Smarty_Internal_Templatelexer
function yy_r1_19($yy_subpatterns)
{
$this->token = Smarty_Internal_Templateparser::TP_PHPENDSCRIPT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
function yy_r1_20($yy_subpatterns)
{
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG;
}
function yy_r1_21($yy_subpatterns)
{
$this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG;
$this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG;
}
function yy_r1_22($yy_subpatterns)
{
$this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG;
}
function yy_r1_23($yy_subpatterns)
{
$clean = preg_replace("/{$this->ldel}\*([\S\s]*?)\*{$this->rdel}/", '', $this->value);
$clean = preg_replace("/{$this->ldel}([\S\s]*?){$this->rdel}/", '', $this->value);
if (preg_match("/<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>/", $clean, $match)) {
$this->phpValue = $match[0];
$this->is_phpScript = true;
$this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG;
$this->compiler->trigger_template_error('Security error: Illegal code injection');
} else {
preg_match("/([\S\s]*?)(?={$this->ldel})/", $this->value, $match);
$this->value = $match[0];
@@ -404,12 +393,12 @@ class Smarty_Internal_Templatelexer
}
}
function yy_r1_28($yy_subpatterns)
function yy_r1_27($yy_subpatterns)
{
$phpEndScript = $this->is_phpScript ? '|<\\/script>' : '';
$to = strlen($this->data);
preg_match("/<\?|<%|\?>|%>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>|<(([^>]*?)(?={$this->ldel}){$this->ldel}\*([\S\s]*?)\*{$this->rdel})+([^>]*?)(?!{$this->ldel})>|{$this->ldel}{$phpEndScript}/", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
preg_match("/<\?|<%|\?>|%>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>|<(([^>]*?)(?={$this->ldel}){$this->ldel}([\S\s]*?){$this->rdel})+([^>]*?)(?!{$this->ldel})>|{$this->ldel}{$phpEndScript}/", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
if (isset($match[0][1])) {
$to = $match[0][1];
}
@@ -993,7 +982,7 @@ class Smarty_Internal_Templatelexer
if ($this->counter >= strlen($this->data)) {
return false; // end of input
}
$yy_global_pattern = "/\G(" . $this->ldel . "\\s*literal\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*\/literal\\s*" . $this->rdel . ")|\G((<script\\s+language\\s*=\\s*[\"']?\\s*php\\s*[\"']?\\s*>)|(<\\?(?:php\\w+|=|[a-zA-Z]+)?))|\G(\\?>)|\G(<\/script>)|\G(<%)|\G(%>)|\G(<(([^>]*?)(?=" . $this->ldel . ")" . $this->ldel . "\\*([\S\s]*?)\\*" . $this->rdel . ")+([^>]*?)(?!" . $this->ldel . ")>)|\G([\S\s])/iS";
$yy_global_pattern = "/\G(" . $this->ldel . "\\s*literal\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*\/literal\\s*" . $this->rdel . ")|\G((<script\\s+language\\s*=\\s*[\"']?\\s*php\\s*[\"']?\\s*>)|(<\\?(?:php\\w+|=|[a-zA-Z]+)?))|\G(\\?>)|\G(<\/script>)|\G(<%)|\G(%>)|\G(<(([^>]*?)(?=" . $this->ldel . ")" . $this->ldel . "([\S\s]*?)" . $this->rdel . ")+([^>]*?)(?!" . $this->ldel . ")>)|\G([\S\s])/iS";
do {
if (preg_match($yy_global_pattern, $this->data, $yymatches, null, $this->counter)) {
@@ -1068,7 +1057,7 @@ class Smarty_Internal_Templatelexer
function yy_r3_3($yy_subpatterns)
{
if ($script = strpos($this->value, '<s') === 0 || in_array($this->value, Array('<?', '<?=', '<?php'))) {
if (($script = strpos($this->value, '<s') === 0) || in_array($this->value, Array('<?', '<?=', '<?php'))) {
if ($script) {
$this->is_phpScript = true;
}
@@ -1106,11 +1095,9 @@ class Smarty_Internal_Templatelexer
function yy_r3_10($yy_subpatterns)
{
$clean = preg_replace("/{$this->ldel}\*([\S\s]*?)\*{$this->rdel}/", '', $this->value);
$clean = preg_replace("/{$this->ldel}([\S\s]*?){$this->rdel}/", '', $this->value);
if (preg_match("/<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>/", $clean, $match)) {
$this->phpValue = $match[0];
$this->is_phpScript = true;
$this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG;
$this->compiler->trigger_template_error('Security error: Illegal code injection');
} else {
preg_match("/([\S\s]*?)(?={$this->ldel})/", $this->value, $match);
$this->value = $match[0];
@@ -1123,7 +1110,7 @@ class Smarty_Internal_Templatelexer
$phpEndScript = $this->is_phpScript ? '|<\\/script>' : '';
$to = strlen($this->data);
preg_match("/<\?|<%|\?>|%>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>|<(([^>]*?)(?={$this->ldel}){$this->ldel}\*([\S\s]*?)\*{$this->rdel})+([^>]*?)(?!{$this->ldel})>|{$this->ldel}\/?literal{$this->rdel}{$phpEndScript}/", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
preg_match("/<\?|<%|\?>|%>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>|{$this->ldel}\/?literal{$this->rdel}{$phpEndScript}/", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
if (isset($match[0][1])) {
$to = $match[0][1];
} else {

File diff suppressed because it is too large Load Diff