- 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) ===== 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 12.10.2014
- bugfix a comment like "<script{*foo*} language=php>" bypassed $php_handling checking (Thue Kristensen) - 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 - 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 // loop over items, stitch back together
foreach ($cache_split as $curr_idx => $curr_split) { foreach ($cache_split as $curr_idx => $curr_split) {
// escape PHP tags in template content // 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])) { if (isset($cache_parts[0][$curr_idx])) {
$_template->properties['has_nocache_code'] = true; $_template->properties['has_nocache_code'] = true;
// remove nocache tags from cache output // remove nocache tags from cache output

View File

@@ -21,7 +21,6 @@ class Smarty_Internal_Templatelexer
public $line; public $line;
public $taglineno; public $taglineno;
public $is_phpScript = false; public $is_phpScript = false;
public $phpValue = '';
public $state = 1; public $state = 1;
public $smarty; public $smarty;
private $heredoc_id_stack = Array(); private $heredoc_id_stack = Array();
@@ -164,14 +163,13 @@ class Smarty_Internal_Templatelexer
19 => 0, 19 => 0,
20 => 0, 20 => 0,
21 => 0, 21 => 0,
22 => 0, 22 => 4,
23 => 4, 27 => 0,
28 => 0,
); );
if ($this->counter >= strlen($this->data)) { if ($this->counter >= strlen($this->data)) {
return false; // end of input 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 { do {
if (preg_match($yy_global_pattern, $this->data, $yymatches, null, $this->counter)) { 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) 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) { if ($script) {
$this->is_phpScript = true; $this->is_phpScript = true;
} }
$this->phpValue = $this->value;
$this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG; $this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG;
} elseif ($this->value == '<?xml') { } elseif ($this->value == '<?xml') {
$this->token = Smarty_Internal_Templateparser::TP_XMLTAG; $this->token = Smarty_Internal_Templateparser::TP_XMLTAG;
@@ -368,35 +365,27 @@ class Smarty_Internal_Templatelexer
function yy_r1_19($yy_subpatterns) 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) 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) 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) function yy_r1_22($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG; $clean = preg_replace("/{$this->ldel}([\S\s]*?){$this->rdel}/", '', $this->value);
}
function yy_r1_23($yy_subpatterns)
{
$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)) { if (preg_match("/<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>/", $clean, $match)) {
$this->phpValue = $match[0]; $this->compiler->trigger_template_error('Security error: Illegal code injection');
$this->is_phpScript = true;
$this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG;
} else { } else {
preg_match("/([\S\s]*?)(?={$this->ldel})/", $this->value, $match); preg_match("/([\S\s]*?)(?={$this->ldel})/", $this->value, $match);
$this->value = $match[0]; $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>' : ''; $phpEndScript = $this->is_phpScript ? '|<\\/script>' : '';
$to = strlen($this->data); $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])) { if (isset($match[0][1])) {
$to = $match[0][1]; $to = $match[0][1];
} }
@@ -993,7 +982,7 @@ class Smarty_Internal_Templatelexer
if ($this->counter >= strlen($this->data)) { if ($this->counter >= strlen($this->data)) {
return false; // end of input 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 { do {
if (preg_match($yy_global_pattern, $this->data, $yymatches, null, $this->counter)) { 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) 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) { if ($script) {
$this->is_phpScript = true; $this->is_phpScript = true;
} }
@@ -1106,11 +1095,9 @@ class Smarty_Internal_Templatelexer
function yy_r3_10($yy_subpatterns) 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)) { if (preg_match("/<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>/", $clean, $match)) {
$this->phpValue = $match[0]; $this->compiler->trigger_template_error('Security error: Illegal code injection');
$this->is_phpScript = true;
$this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG;
} else { } else {
preg_match("/([\S\s]*?)(?={$this->ldel})/", $this->value, $match); preg_match("/([\S\s]*?)(?={$this->ldel})/", $this->value, $match);
$this->value = $match[0]; $this->value = $match[0];
@@ -1123,7 +1110,7 @@ class Smarty_Internal_Templatelexer
$phpEndScript = $this->is_phpScript ? '|<\\/script>' : ''; $phpEndScript = $this->is_phpScript ? '|<\\/script>' : '';
$to = strlen($this->data); $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])) { if (isset($match[0][1])) {
$to = $match[0][1]; $to = $match[0][1];
} else { } else {

File diff suppressed because it is too large Load Diff