跳转到内容

转义器


概览

网站和 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);
// &lt;/title&gt;&lt;script&gt;alert(1)&lt;/script&gt;

$css = ';`(';
echo $escaper->css($css);
// &#x3c &#x2f style&#x3e

$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);
// &lt;/title&gt;&lt;script&gt;alert(1)&lt;/script&gt;

HTML 语法:

<?php echo $this->escaper->html($title); ?>

Volt 语法:

{{ title | escape }}

HTML 属性

转义属性与转义 HTML 内容不同。转义器通过将每个非字母数字字符转换为安全格式来工作。它内部使用htmlspecialchars。这种转义旨在排除复杂的表达式,例如hrefurl。要转义属性,您可以使用attributes()方法。此方法已被重命名。旧方法escapeHtmlAttr()将在未来删除并发出@deprecated警告。

该方法还接受一个数组作为参数。键是属性名称,值是属性值。如果值是布尔值(true/false),则该属性将没有值:

['disabled' => true] -> 'disabled`

结果字符串中的属性对将以空格分隔。

<?php

use Phalcon\Html\Escaper;

$escaper = new Escaper();

$attr = '"><h1>Hello</table';
echo $escaper->attributes($attr);
// &#x22;&#x3e;&#x3c;h1&#x3e;Hello&#x3c;&#x2f;table

HTML 语法:

<?php echo $this->escaper->attributes($attr); ?>

Volt 语法:

{{ attr | escape_attr }}

URL

url()可用于转义如hrefurl转义。此方法已被重命名。旧方法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 语法:

<?php echo $this->escaper->attributes($url); ?>

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 语法:

<?php echo $this->escaper->css($css); ?>

Volt 语法:

{{ css | escape_css }}

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 语法:

<?php echo $this->escaper->js($js); ?>

Volt 语法:

{{ js | escape_js }}

编码

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()

返回转义器使用的内部编码

<?php

use Phalcon\Html\Escaper;

$escaper = new Escaper();

echo $escaper->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)

<?php

use Phalcon\Html\Escaper;

$escaper = new Escaper();

$escaper->setDoubleEncode(false);

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

<?php

use Phalcon\Html\Escaper;

$escaper = new Escaper();

$escaper->setFlags(ENT_XHTML);

异常

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;
}
无噪 Logo
无噪文档
25 年 6 月翻译
文档源↗