esperecyan/html-filter

这是一个简单的HTML过滤器,通过白名单来检查元素名和属性名。

v1.3.0 2020-01-25 02:48 UTC

This package is auto-updated.

Last update: 2024-08-25 14:09:55 UTC


README

这是一个通过白名单检查元素名和属性的HTML过滤器。不执行HTML验证。

示例

<?php
require_once 'vendor/autoload.php';

use esperecyan\webidl\TypeError;
use esperecyan\url\URL;

$filter = new \esperecyan\html_filter\Filter([
    '*' => [
        'dir' => ['ltr', 'rtl', 'auto'],
        'lang' => '/^[a-z]+(-[0-9a-z]+)*$/iu',
        'title',
        'translate' => ['', 'yes', 'no'],
    ],
    'a' => ['href' => 'isURLWithNetworkScheme'],
    'br',
    'img' => ['alt', 'src' => 'isURLWithNetworkScheme'],
    'p',
    'time' => 'datetime',
]);
$filter->setLogger(new class extends \Psr\Log\AbstractLogger {
    public function log($level, $message, array $context = []) {
        echo "$level: $message\n";
    }
});
var_dump($filter->filter(<<<'EOD'
<script>
    window.alert('foobar');
</script>
<a href="https://example.com/">例示用ドメイン</a>
<a href="./file.html" title="テスト">相対URL</a>
<bR data-clear="">
<p dir="ltr" lang='"invalid"'>アリス</p>
<p dir="LtR" LanG='ja'>ボブ</p>
EOD
));

function isURLWithNetworkScheme(string $value): bool {
    try {
        $url = new URL($value);
    } catch (TypeError $exception) {
        return false;
    }
    return in_array($url->protocol, ['ftp:', 'http:', 'https:']);
}

上面的示例输出如下。

notice: <script> タグの使用は許可されていません。
notice: <a> タグの href 属性値 "./file.html" は許可されていません。
notice: <br> タグの data-clear 属性の使用は許可されていません。
notice: <p> タグの lang 属性値 "&quot;invalid&quot;" は許可されていません。
notice: <p> タグの dir 属性値 "LtR" は許可されていません。
example.php:33:
string(179) "
    window.alert('foobar');

<a href="https://example.com/">例示用ドメイン</a>
<a title="テスト">相対URL</a>
<br />
<p dir="ltr">アリス</p>
<p lang="ja">ボブ</p>"

安装

composer require esperecyan/html-filter

有关Composer安装方法,请参阅Composer的全局安装 - Qiita等。

要求

  • PHP 7.0以上

用法

将白名单传递给esperecyan\html_filter\Filter构造函数的第一个参数。传递输入字符串给filter方法的第一个参数,可以得到HTML或XHTML格式的字符串。

此库只能处理作为body元素后代的片段HTML。无法正常处理包含xmlns属性的文档,以及具有http://www.w3.org/1999/xhtml以外的命名空间(如svg元素、math元素)及其后代元素。同时,也会移除注释等。

白名单

注释始终是过滤对象。

选项

将关联数组传递给esperecyan\html_filter\Filter构造函数的第二个参数。如果为每个选项传递null,则忽略该指定。

日志记录

esperecyan\html_filter\Filter实现了PSR-3: Logger InterfacePsr\Log\LoggerAwareInterface

Psr\Log\LogLevel::NOTICE的情况

注意

即使没有任何日志输出,也可能无法将输入作为XHTML处理。如果要在XHTML中嵌入,请通过esperecyan\html_filter\Filter->filter()输出。

<?php
$filter = new \esperecyan\html_filter\Filter(['a', 'blockquote', 'code', 'h1', 'h2', 'pre']);
$filter->setLogger(new class extends \Psr\Log\AbstractLogger {
    public function log($level, $message, array $context = []) use ($logged) {
        $logged = true;
    }
});
$output = $filter->filter($input);

$storage = $logged ? $output : $input;
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>XHTML文書</title>
    </head>
    <body>
        <?= (new \esperecyan\html_filter\Filter())->filter($storage) ?>
    </body>
</html>

贡献

请通过Pull Request或Issue进行贡献。

语义化版本控制

本库采用语义化版本控制。公共API仅限于esperecyan\html_filter\Filter类的public方法。

许可

本库的许可为Mozilla Public License Version 2.0 (MPL-2.0)。