esperecyan/html-filter

ホワイトリストによる要素名と属性名のチェックを行うシンプルなHTMLフィルターです。

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

This package is auto-updated.

Last update: 2024-11-25 14:41:36 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コンストラクタの第1引数に、ホワイトリストを与えます。 インスタントのfilterメソッドの第1引数に入力文字列を与えると、HTMLとしてもXHTMLとしても扱える文字列を返します。

当ライブラリは、body要素の子孫としての断片的なHTMLしか扱えません。 また、xmlns属性を含む文書は正常に取り扱うことができず、 http://www.w3.org/1999/xhtml 以外の名前空間を持つ要素 (svg要素、math要素)、およびその子孫は強制的に取り除かれます。 また、コメントなども取り除かれます。

ホワイトリスト

コメントは常にフィルタリング対象となります。

オプション

esperecyan\html_filter\Filterコンストラクタの第2引数に連想配列で与えます。 各オプションにnullを与えた場合、指定は無視されます。

ロギング

esperecyan\html_filter\FilterPSR-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>

Contribution

Pull Request、または Issue よりお願いいたします。

セマンティック バージョニング

当ライブラリはセマンティック バージョニングを採用しています。 パブリックAPIは、esperecyan\html_filter\Filterクラスのpublicメソッドのみです。

ライセンス

当ライブラリのライセンスは Mozilla Public License Version 2.0 (MPL-2.0) です。