转义器¶
概览¶
网站和 Web 应用程序容易受到XSS攻击的影响,尽管 PHP 提供了转义功能,但在某些上下文中,这种功能并不足够或不适当。Phalcon\Html\Escaper提供上下文相关的转义,并且是用Zephir编写的,从而在转义不同类型文本时提供极小的开销。
我们根据XSS(跨站脚本攻击)防御备忘单(由OWASP创建)设计了这个组件。此外,该组件依赖于mbstring来支持几乎任何字符集。为了说明该组件的工作原理及其重要性,请考虑以下示例:
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$title = '</title><script>alert(1)</script>';
echo $escaper->html($title);
// </title><script>alert(1)</script>
$css = ';`(';
echo $escaper->css($css);
// < / style>
$fontName = 'Verdana\"</style>';
echo $escaper->css($fontName);
// Verdana\22 \3c \2f style\3e
$js = "';</script>Hello";
echo $escaper->js($js);
// \x27\x3b\x3c\2fscript\x3eHello
HTML¶
您可以在将文本打印到视图之前对其进行转义,使用html()如果不进行转义,则可能会在 HTML 输出中回显不安全的数据。
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$title = '</title><script>alert(1)</script>';
echo $escaper->html($title);
// </title><script>alert(1)</script>
HTML 语法:
Volt 语法:
HTML 属性¶
转义属性与转义 HTML 内容不同。转义器通过将每个非字母数字字符转换为安全格式来工作。它内部使用htmlspecialchars。这种转义旨在排除复杂的表达式,例如href或url。要转义属性,您可以使用attributes()方法。此方法已被重命名。旧方法escapeHtmlAttr()将在未来删除并发出@deprecated警告。
该方法还接受一个数组作为参数。键是属性名称,值是属性值。如果值是布尔值(true/false),则该属性将没有值:
结果字符串中的属性对将以空格分隔。
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$attr = '"><h1>Hello</table';
echo $escaper->attributes($attr);
// "><h1>Hello</table
HTML 语法:
Volt 语法:
URL¶
url()可用于转义如href或url转义。此方法已被重命名。旧方法escapeUrl()将在未来删除并发出@deprecated警告。
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$url = '"><script>alert(1)</script><a href="#';
echo $escaper->attributes($url);
// %22%3E%3Cscript%3Ealert%281%29%3C%2Fscript%3E%3Ca%20href%3D%22%23
HTML 语法:
CSS¶
CSS 标识符/值可以通过使用css()转义。此方法已被重命名。旧方法escapeCss()将在未来删除并发出@deprecated警告。
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$css = '"><script>alert(1)</script><a href="#';
echo $escaper->css($css);
// \22 \3e \3c script\3e alert\28 1\29 \3c \2f script\3e \3c a\20 href\3d \22 \23 
HTML 语法:
Volt 语法:
JavaScript¶
打印到 JavaScript 代码中的内容必须正确转义。js()帮助完成此任务。此方法已被重命名。旧方法escapeJs()将在未来删除并发出@deprecated警告。
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$js = "'; alert(100); var x='";
echo $escaper->js($js);
// \x27; alert(100); var x\x3d\x27
HTML 语法:
Volt 语法:
编码¶
Phalcon\Html\Escape还提供了与待转义文本编码相关的方法。
detectEncoding()¶
 检测要由编码器处理的字符串的字符编码。特殊处理针对无法检测到的情况chr(172)和chr(128)到chr(159) which fail to be detected mb_detect_encoding。该方法返回一个string包含检测到的编码或null
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
echo $escaper->detectEncoding('ḂḃĊċḊḋḞḟĠġṀṁ'); // UTF-8
getEncoding()¶
 返回转义器使用的内部编码
normalizeEncoding()¶
 工具方法,将字符串的编码规范化为 UTF-32。
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
echo $escaper->normalizeEncoding('ḂḃĊċḊḋḞḟĠġṀṁ');  
setEncoding()¶
 设置转义器使用的编码
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$escaper->setEncoding('utf-8');
echo $escaper->getEncoding(); // 'utf-8'
setDoubleEncode()¶
 设置转义器是否使用双重编码(默认值true)
setFlags(int $flags)¶
 您可以设置转义器使用的引号类型。此方法已被重命名。旧方法setHtmlQuoteType()将在未来删除并发出@deprecated警告。
传递的变量是htmlspecialchars接受的常量之一:-ENT_COMPAT - ENT_QUOTES - ENT_NOQUOTES - ENT_IGNORE - ENT_SUBSTITUTE - ENT_DISALLOWED - ENT_HTML401 - ENT_XML1 - ENT_XHTML - ENT_HTML5
异常¶
Escaper 组件抛出的所有异常都将为类型Phalcon\Html\Escaper\Exception。当提供给组件的数据无效时会抛出此异常。您可以通过这些异常选择性地捕获仅从此组件抛出的异常。
<?php
use Phalcon\Html\Escaper;
use Phalcon\Html\Escaper\Exception;
use Phalcon\Mvc\Controller;
/**
 * @property Escaper $escaper
 */
class IndexController extends Controller
{
    public function index()
    {
        try {
            echo $this->escaper->normalizeEncoding('ḂḃĊċḊḋḞḟĠġṀṁ');  
        } catch (Exception $ex) {
            echo $ex->getMessage();
        }
    }
}
依赖注入¶
如果您使用Phalcon\Di\FactoryDefault容器,Phalcon\Html\Escaper已经为您以名称escaper.
注册。下面是一个注册服务以及访问它的示例:
<?php
use Phalcon\Di\Di;
use Phalcon\Html\Escaper;
$container = new Di();
$container->set(
    'escaper',
    function () use  {
        return new Escaper();
    }
);
现在您可以在控制器中(或实现 Phalcon\Di\Injectable 的组件中)使用该组件。
<?php
namespace MyApp;
use Phalcon\Html\Escaper;
use Phalcon\Mvc\Controller;
/**
 * Invoices controller
 *
 * @property Escaper $escaper
 */
class InvoicesController extends Controller
{
    public function indexAction()
    {
    }
    public function saveAction()
    {
        echo $this->escaper->html('The post was correctly saved!');
    }
}
自定义¶
Phalcon 还提供了Phalcon\Html\Escaper\EscaperInterface,可以在自定义类中实现。该类可以提供您所需的转义功能。
<?php
namespace MyApp\Escaper;
use Phalcon\Html\Escaper\EscaperInterface;
class Custom extends EscaperInterface
{
    public function css(string $css): string;
    public function html(string $text): string;
    public function attributes(string $text): string;
    public function js(string $js): string;
    public function url(string $url): string;
    public function getEncoding(): string;
    public function setEncoding(string $encoding): void;
    public function setHtmlQuoteType(int $quoteType): void;
}