
PHP-библиотека, которая очищает недоверенные SVG/XML-файлы, фильтруя теги, атрибуты и удалённые ссылки, чтобы предотвратить XSS и внедрение скриптов в загруженные или встроенные SVG-файлы.
Это моя попытка создать достойный SVG-санитайзер на PHP. Работа во многом заимствована из DOMPurify.
Либо подключите enshrined/svg-sanitize через composer, либо скачайте репозиторий и подключите старым способом!
Использовать это довольно просто. Создайте новый экземпляр enshrined\svgSanitize\Sanitizer, а затем вызовите sanitize, передав в него ваш неочищенный SVG/XML
Базовый пример
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, либо логическое значение false, если разбор XML завершился неудачей (обычно из-за плохо отформатированного файла).
Он также возвращает false для входных данных, которые не будут переданы XML-парсеру:
<svg> в пространстве имён, отличном от SVGgetXmlIssues() сообщает причину.
Вы можете передать собственный белый список тегов и атрибутов, используя методы Sanitizer::setAllowedTags и Sanitizer::setAllowedAttrs соответственно.
Эти методы требуют, чтобы вы реализовали enshrined\svgSanitize\data\TagInterface или enshrined\svgSanitize\data\AttributeInterface.
<use> разрешён по умолчанию, но с ограничениями на то, насколько далеко могут расширяться ссылки (useThreshold()) и вкладываться друг в друга (setUseNestingLimit()). Если он вам не нужен, например потому что вы встраиваете недоверенный SVG прямо в свои страницы, исключите use из белого списка тегов, чтобы убрать всю эту область.
У вас есть возможность удалять атрибуты, ссылающиеся на удалённые файлы; это остановит утечки через HTTP, но добавит накладные расходы санитайзеру.
По умолчанию это значение равно false; установите true, чтобы удалять ссылки.
$sanitizer->removeRemoteReferences(true);
При включении удалённые ссылки также вырезаются из CSS внутри элементов <style> и из CSS в атрибутах (url(), @import, image-set() и строк в кавычках, начинающихся с удалённого URL). Атрибуты srcset удаляются полностью, поскольку они содержат список URL. Эта обработка CSS выполняется по мере возможности: это не полноценный CSS-парсер. Рассматривайте её как дополнительный уровень защиты, а не как гарантию, и изолируйте недоверенный CSS в точке встраивания SVG.
Примечание: если элемент <style> или атрибут style содержит удалённую ссылку, которая вырезается, то любые CSS-escape-последовательности в этом же блоке нормализуются (декодируются) в выводе. Это семантически идентичный CSS, но он перезапишет escape-последовательности, написанные автором вручную.
Вы можете использовать метод getXmlIssues() для получения массива проблем, возникших во время санитизации.
Это может быть полезно для логирования или для информирования пользователя о том, почему SVG был отклонён.
$issues = $sanitizer->getXmlIssues();
Список содержит до 1 000 проблем. Если их больше, последняя запись сообщает, сколько было опущено.
Вы можете минифицировать вывод XML, вызвав $sanitizer->minify(true);.
Демо доступно по адресу: 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!