Веб-сайты и веб-приложения уязвимы для XSS-атак, и хотя PHP предоставляет экранирующие функции,в некоторых контекстах этого недостаточно. Phalcon\Escaper обеспечивает контекстное экранирование и записывается в Zephir, обеспечивая минимальные накладные расходы при экранировании различных видов текстов.

Мы разработали этот компонент на основе прошивки XSS (Cross Site Scripting) Prevention Cheat Sheet, созданной OWASP.

Кроме того, этот компонент полагается на mbstring для поддержки почти любой кодировки.

Чтобы проиллюстрировать, как работает этот компонент и почему он важен, рассмотрите следующий пример:

<?php

use Phalcon\Escaper;

// Название документа со злонамеренными дополнительными тегами HTML
$maliciousTitle = "</title><script>alert(1)</script>";

// Название класса злонамеренного CSS
$className = ";`(";

// Имя шрифта вредоносного CSS
$fontName = "Verdana\"</style>";

// Вредоносный текст Javascript
$javascriptText = "';</script>Hello";

// Создание эскператора
$e = new Escaper();

?>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <title>
            <?php echo $e->escapeHtml($maliciousTitle); ?>
        </title>

        <style type="text/css">
            .<?php echo $e->escapeCss($className); ?> {
                font-family: "<?php echo $e->escapeCss($fontName); ?>";
                color: red;
            }
        </style>

    </head>

    <body>

        <div class='<?php echo $e->escapeHtmlAttr($className); ?>'>
            hello
        </div>

        <script>
            var some = '<?php echo $e->escapeJs($javascriptText); ?>';
        </script>

    </body>
</html>

Что дает следующее:

&lt;html&gt;
    &lt;head&gt;
        &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;

        &lt;title&gt;
            &lt;/title&gt;&lt;script&gt;alert(1)&lt;/script&gt;
        &lt;/title&gt;

        &lt;style type="text/css"&gt;
            .\3c \2f style\3e {
                font-family: "Verdana\22 \3c \2f style\3e";
                color: red;
            }
        &lt;/style&gt;

    &lt;/head&gt;

    &lt;body&gt;

        &lt;div class='&#x3c &#x2f style&#x3e '&gt;
            hello
        &lt;/div&gt;

        &lt;script&gt;
            var some = '\x27\x3b\x3c\2fscript\x3eHello';
        &lt;/script&gt;

    &lt;/body&gt;
&lt;/html&gt;

Каждый текст был экранирован в соответствии с его контекстом. Использовать соответствующий контекст важно, чтобы избежать атак XSS.

Экранирование HTML

Наиболее распространенная ситуация при вставке небезопасных данных находится между тегами HTML:

<div class="comments">
    <!-- Escape untrusted data here! -->
</div>

Вы можете избежать этих данных с помощью метода escapeHtml:

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

Что производит:

<div class="comments">
    &gt;&lt;/div&gt;&lt;h1&gt;myattack&lt;/h1&gt;
</div>

Экранирование атрибутов HTML

Экранирование атрибутов HTML отличается от экранирования содержимого HTML. Эскейпер работает, изменяя каждый не алфавитно-цифровой символ на форму. Этот вид экранирования предназначен для наиболее простых атрибутов, исключая сложные, такие как href или url:

<table width="Escape untrusted data here!">
    <tr>
        <td>
            Hello
        </td>
    </tr>
</table>

Можно экранировать атрибут HTML с помощью метода escapeHtmlAttr:

<table width="<?php echo $e->escapeHtmlAttr('"><h1>Hello</table'); ?>">
    <tr>
        <td>
            Hello
        </td>
    </tr>
</table>

Производящий:

<table width="&#x22;&#x3e;&#x3c;h1&#x3e;Hello&#x3c;&#x2f;table">
    <tr>
        <td>
            Hello
        </td>
    </tr>
</table>

Экранирование URL-Адресов

Некоторые атрибуты HTML, такие как href или url, должны быть экранированы по-разному:

<a href="/Escape untrusted data here!">
    Some link
</a>

Можно экранировать атрибут HTML с помощью метода escapeUrl:

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

Производящий:

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

Экранирование CSS

CSS идентификаторы / значения также могут быть экранированы:

<a style="color: Escape untrusted data here">
    Some link
</a>

Можно экранировать идентификаторы CSS / значение с помощью метода: escapeCss:

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

Производящий:

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

Экранирование JavaScript

Строк, которые будут вставлены в код JavaScript, также должны быть правильно экранированы:

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

Код JavaScript можно экранировать с помощью метода escapeJs:

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

Производящий:

<script>
    document.title = '\x27; alert(100); var x\x3d\x27';
</script>