2

我正在采用 Twig(一个 php 模板框架)的一些代码来转义 html 和 js 输出。现在我不完全理解他们使用的正则表达式。

对于完整的 Twig 代码:

git clone git://github.com/fabpot/Twig.git
// the code is in Core.php in the function twig_escape_filter

他们使用:

preg_replace_callback( '#[^a-zA-Z0-9,\._]#Su'   , '_twig_escape_js_callback'               , $string ); // for javascript
preg_replace_callback( '#[^a-zA-Z0-9,\.\-_]#Su' , '_twig_escape_html_attr_callback' , $string ); // for html attibutes

回调函数将替换与否定字符类对应的所有内容。

据我所知,这是等价的(去掉一些反斜杠):

'#[^a-zA-Z0-9,._]#Su'
'#[^a-zA-Z0-9,._-]#Su'

现在我们看到,对于 javascript,它们允许使用逗号,我不明白,因为逗号是 javascript 上下文中的控制字符。举一个逗号利用的例子:

// say we have a function call to a javascript function like this
function ajax( timeout, onerror, onsuccess ) {...};

// now assume I get the timeout value from somewhere dodgy (in php)
$timeout = escapeJS( '1000, evilCallback, evilCallback2' );

echo "ajax( $timeout, myErrorHandler, mySuccessHandler );"

请注意,javascript会很乐意忽略额外的参数......

在 html 属性中,想法是防止关闭属性,因此它们不允许空格,因为不带引号的属性很常见,并且在 html4 中也是合法的。但是,我看到属性中使用空格来为元素提供多个类,例如:<tr class="tablerow odd">. 因此,不允许使用空格可以防止像这样的类属性来自带有模板或其他来源的数据库......

  1. 鉴于在 xhtml 中禁止使用不带引号的属性,并且我的网站生成 xhtml 严格的文档类型,我可以允许空格吗?
  2. 我应该禁止 javascript 的逗号吗?
4

2 回答 2

1

您应该使用htmlspecialchars转义 HTML 和json_encode转义 Javascript。

$timeout = json_encode('1000, evilCallback, evilCallback2');
echo "ajax( $timeout, myErrorHandler, mySuccessHandler );";

输出:

ajax( "1000, evilCallback, evilCallback2", myErrorHandler, mySuccessHandler );

在您的情况下,您还应该验证$timeoutvar 的实际内容,或将其转换为 int,如下所示:

$timeout = json_encode((int)'1000, evilCallback, evilCallback2');
echo "ajax( $timeout, myErrorHandler, mySuccessHandler );";

输出:

ajax( 1000, myErrorHandler, mySuccessHandler );

json_encode您转换为 int 时,实际上并不需要 ,因为 PHP 整数也是有效的 JS 整数,但是为适当的上下文转义所有数据是一个好习惯。


更新:关于您尝试调整的 Twig 代码,它似乎不会产生实际的 Javascript 文字,而是转义字符串以包含Javascript 文字中——这从转义码的实际使用中可以明显看出\xHH,这在 JS 中仅有效内部字符串(和正则表达式,但这不是重点)。它应该这样使用:

$timeout = escapeJS('1000, evilCallback, evilCallback2');
echo "ajax('$timeout', myErrorHandler, mySuccessHandler);";

请注意$timeout. echo这样做很可能是为了允许从多个转义部分(如'foo $escaped_part1 bar $escaped_part2 baz'.

于 2012-07-08T16:51:09.220 回答
0

我在XSS(跨站点脚本)预防备忘单上发现的内容:

对于 HTML 属性:

正确引用的属性只能使用相应的引号进行转义。不带引号的属性可以用许多字符分开,包括 [space] % * + , - / ; < = > ^ 和 |。

我想这样看待它意味着没有办法既能防止未引用的属性又能在属性中包含空格。我想转义函数可以自己添加引号,但这与创建情况不一致,其中 vulues 将被引用两次,基本上不引用它们......所以,现在我已经制作了两个转义函数,允许用户显式调用一个这允许空间,知道他们必须加上引号。

考虑到javascript:

除字母数字字符外,使用 \xHH 格式转义所有小于 256 的字符,以防止将数据值切换到脚本上下文或其他属性中。不要使用像 \" 这样的转义快捷方式,因为引号字符可能会被首先运行的 HTML 属性解析器匹配。这些转义快捷方式也容易受到攻击者发送 \" 和易受攻击的代码的“转义”攻击将其转换为 \" 以启用报价。

如果事件处理程序被正确引用,则爆发需要相应的引用。然而,我们有意使这条规则非常宽泛,因为事件处理程序属性通常不加引号。不带引号的属性可以用许多字符分开,包括 [space] % * + , - / ; < = > ^ 和 |。此外,关闭标记将关闭脚本块,即使它位于带引号的字符串内,因为 HTML 解析器在 JavaScript 解析器之前运行。

这似乎表明我们应该逃避一切。我选择保留下划线,因为它可以是 javascript 名称和点的一部分,以便允许插入带小数点的数值。我希望这不会留下任何漏洞。

我想 Twig 代码有一个错误,会留下逗号,我会提交一份报告,以便他们调查。

于 2012-07-08T23:12:15.997 回答