
これは、PHP でまともな SVG サニタイザーを構築するための私の試みです。作業の大部分は DOMPurify から借用しています。
composer 経由で enshrined/svg-sanitize を要求するか、リポジトリをダウンロードして従来の方法でインクルードしてください!
使い方は非常に簡単です。enshrined\svgSanitize\Sanitizer の新しいインスタンスを作成し、汚染された SVG/XML を渡しながら sanitize を呼び出します。
基本的な例
use enshrined\svgSanitize\Sanitizer;
// Create a new sanitizer instance
$sanitizer = new Sanitizer();
// Load the dirty svg
$dirtySVG = file_get_contents('filthy.svg');
// Pass it to the sanitizer and get it back clean
$cleanSVG = $sanitizer->sanitize($dirtySVG);
// Now do what you want with your clean SVG/XML data
これはサニタイズされた SVG/XML 文字列を返すか、XML のパースに失敗した場合(通常はファイルの形式が不正な場合)は真偽値 false を返します。
また、XML パーサーに渡さない入力に対しても false を返します:
<svg> ルート理由は getXmlIssues() で確認できます。
Sanitizer::setAllowedTags および Sanitizer::setAllowedAttrs メソッドをそれぞれ使用して、独自のタグと属性のホワイトリストを渡すことができます。
これらのメソッドでは、enshrined\svgSanitize\data\TagInterface または enshrined\svgSanitize\data\AttributeInterface を実装する必要があります。
<use> はデフォルトで許可されていますが、参照の展開範囲(useThreshold())とネスト(setUseNestingLimit())には制限があります。不要な場合、たとえば信頼できない SVG をページにインライン展開する場合は、タグの許可リストから use を外すことでこの領域全体を削除できます。
リモートファイルを参照する属性を削除するオプションがあります。これにより HTTP リークは防げますが、サニタイザーにオーバーヘッドが追加されます。
デフォルトは false で、参照を削除するには true に設定します。
$sanitizer->removeRemoteReferences(true);
有効にすると、リモート参照は <style> 要素内の CSS や属性内の CSS(url()、@import、image-set()、およびリモート URL で始まる引用文字列)からも除去されます。srcset 属性は URL のリストを保持するため、完全に削除されます。この CSS 処理はベストエフォートであり、完全な CSS パーサーではありません。保証ではなく多層防御として扱い、信頼できない CSS は SVG を埋め込む時点で分離してください。
注: <style> 要素または style 属性に除去対象のリモート参照が含まれている場合、同じブロック内の CSS エスケープシーケンスは出力時に正規化(デコード)されます。これは意味的には同一の CSS ですが、作者が手書きしたエスケープが書き換えられます。
getXmlIssues() メソッドを使用すると、サニタイズ中に発生した問題の配列を返すことができます。
これはログ記録や、SVG が拒否された理由をユーザーにフィードバックする際に役立ちます。
$issues = $sanitizer->getXmlIssues();
リストには最大 1,000 件の問題が保持されます。それ以上ある場合、最後のエントリに省略された件数が示されます。
$sanitizer->minify(true); を呼び出すことで、XML 出力を圧縮できます。
デモはこちらで利用できます: http://svg.enshrined.co.uk/
このコードを含む WordPress プラグインをリリースしたので、WordPress のアップロードをサニタイズできます。WordPress プラグインディレクトリから入手できます: https://wordpress.org/plugins/safe-svg/
Michael Potter 氏がこのライブラリ用の Drupal モジュールを快く作成しており、以下から入手できます: https://www.drupal.org/project/svg_sanitizer
この SVG サニタイザーライブラリは、TYPO3 v9 以降のコアでデフォルトで使用されています。 詳細は対応する変更履歴エントリを参照してください。
このパッケージのベースディレクトリから vendor/bin/phpunit を実行することで実行できます。
gudmdharalds 氏の作業のおかげで、CLI から使用できるスタンドアロンスキャナーが利用可能になりました。
エラーは JSON 形式で出力されます。例についてはこちらの PR を参照してください。
次のように使用します: php svg-scanner.php ~/svgs/myfile.svg
SVG/XML に対するより広範なテストがあると素晴らしいので、近いうちに追加しようと思います。代わりにやってみたいという方は、ぜひ PR を作成してください!