上下文编码(Contextual Escaping)

网站及其它B/S应用极易受到 XSS 攻击,尽管PHP提供了转义功能,在某些情况下依然不够安全。在Phalcon中 Phalcon\Escaper 提供了上下文转义功能,这个模块是由C语言实现的, 这在进行转义时可以有更好的性能。

Phalcon的上下文转义组件基于 OWASP 提供的`XSS (Cross Site Scripting) 预防作弊表`_

另外,这个组件依赖于 mbstring 扩展,以支持几乎所有的字符集。

下面的例子中展示了这个组件是如何工作的:

  1. <?php
  2. use Phalcon\Escaper;
  3. // 带有额外的html标签的恶意的文档标题
  4. $maliciousTitle = "</title><script>alert(1)</script>";
  5. // 恶意的css类名
  6. $className = ";`(";
  7. // 恶意的css字体名
  8. $fontName = "Verdana\"</style>";
  9. // 恶意的Javascript文本
  10. $javascriptText = "';</script>Hello";
  11. // 创建转义实例对象
  12. $e = new Escaper();
  13. ?>
  14. <html>
  15. <head>
  16. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  17. <title>
  18. <?php echo $e->escapeHtml($maliciousTitle); ?>
  19. </title>
  20. <style type="text/css">
  21. .<?php echo $e->escapeCss($className); ?> {
  22. font-family: "<?php echo $e->escapeCss($fontName); ?>";
  23. color: red;
  24. }
  25. </style>
  26. </head>
  27. <body>
  28. <div class='<?php echo $e->escapeHtmlAttr($className); ?>'>
  29. hello
  30. </div>
  31. <script>
  32. var some = '<?php echo $e->escapeJs($javascriptText); ?>';
  33. </script>
  34. </body>
  35. </html>

结果如下:

  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  4. <title>
  5. &lt;/title&gt;&lt;script&gt;alert(1)&lt;/script&gt;
  6. </title>
  7. <style type="text/css">
  8. .\3c \2f style\3e {
  9. font-family: "Verdana\22 \3c \2f style\3e";
  10. color: red;
  11. }
  12. </style>
  13. </head>
  14. <body>
  15. <div class='&#x3c &#x2f style&#x3e '>
  16. hello
  17. </div>
  18. <script>
  19. var some = '\x27\x3b\x3c\2fscript\x3eHello';
  20. </script>
  21. </body>
  22. </html>

Phalcon会根据文本所处的上下文进行转义。 恰当的上下文环境对防范XSS攻击来说是非常重要的。

HTML 编码(Escaping HTML)

最不安全的情形即是在html标签中插入非安全的数据。

  1. <div class="comments">
  2. <!-- Escape untrusted data here! -->
  3. </div>

我们可以使用 escapeHtml 方法对这些文本进行转义:

  1. <div class="comments">
  2. <?php echo $e->escapeHtml('></div><h1>myattack</h1>'); ?>
  3. </div>

结果如下:

  1. <div class="comments">
  2. &gt;&lt;/div&gt;&lt;h1&gt;myattack&lt;/h1&gt;
  3. </div>

HTML 属性编码(Escaping HTML Attributes)

对html属性进行转义和对html内容进行转义略有不同。对html的属性进行转义是通过对所有的非字母和数字转义来实现的。类例的转义都会如此进行的,除了一些复杂的属性外如:href和url:

  1. <table width="Escape untrusted data here!">
  2. <tr>
  3. <td>
  4. Hello
  5. </td>
  6. </tr>
  7. </table>

我们这里使用 escapeHtmlAttr 方法对html属性进行转义:

  1. <table width="<?php echo $e->escapeHtmlAttr('"><h1>Hello</table'); ?>">
  2. <tr>
  3. <td>
  4. Hello
  5. </td>
  6. </tr>
  7. </table>

结果如下:

  1. <table width="&#x22;&#x3e;&#x3c;h1&#x3e;Hello&#x3c;&#x2f;table">
  2. <tr>
  3. <td>
  4. Hello
  5. </td>
  6. </tr>
  7. </table>

URL 编码(Escaping URLs)

一些html的属性如href或url需要使用特定的方法进行转义:

  1. <a href="Escape untrusted data here!">
  2. Some link
  3. </a>

我们这里使用 escapeUrl 方法进行url的转义:

  1. <a href="<?php echo $e->escapeUrl('"><script>alert(1)</script><a href="#'); ?>">
  2. Some link
  3. </a>

结果如下:

  1. <a href="%22%3E%3Cscript%3Ealert%281%29%3C%2Fscript%3E%3Ca%20href%3D%22%23">
  2. Some link
  3. </a>

CSS 编码(Escaping CSS)

CSS标识/值也可以进行转义:

  1. <a style="color: Escape untrusted data here">
  2. Some link
  3. </a>

这里我们使用 escapeCss 方法进行转义:

  1. <a style="color: <?php echo $e->escapeCss('"><script>alert(1)</script><a href="#'); ?>">
  2. Some link
  3. </a>

结果:

  1. <a style="color: \22 \3e \3c script\3e alert\28 1\29 \3c \2f script\3e \3c a\20 href\3d \22 \23 ">
  2. Some link
  3. </a>

JavaScript 编码(Escaping JavaScript)

插入JavaScript代码的字符串也需要进行适当的转义:

  1. <script>
  2. document.title = 'Escape untrusted data here';
  3. </script>

这里我们使用 escapeJs 进行转义:

  1. <script>
  2. document.title = '<?php echo $e->escapeJs("'; alert(100); var x='"); ?>';
  3. </script>
  1. <script>
  2. document.title = '\x27; alert(100); var x\x3d\x27';
  3. </script>