Как проверить SVG-файл на встроенный JavaScript

Клиент присылает логотип в SVG, дизайнер загружает иконку с фриланс-биржи, контент-менеджер вставляет картинку на сайт — и вдруг браузер начинает вести себя странно, а потом выясняется, что внутри графики спрятался скрипт. Знакомая история? Давайте разберёмся, как быстро и надёжно проверить SVG на наличие внедрённого JavaScript, не будучи программистом с десятилетним стажем.

Почему SVG может содержать скрипты

SVG — это не просто картинка. Формат основан на XML и изначально поддерживает интерактивность: анимацию, обработку кликов, запуск кода. Это открывает возможности для создания сложной векторной графики, но одновременно создаёт брешь в безопасности.

Злоумышленник может встроить в SVG:

  • <script> с произвольным JavaScript-кодом
  • обработчики событий: onload, onclick, onerror, onmouseover
  • ссылки на внешние скрипты через <script href="...">
  • SVG-анимации (<animate>, <animateEvent>), которые триггерят выполнение кода
  • внедрение через <foreignObject> с HTML и JavaScript внутри

Когда такой файл загружается в браузер пользователя, встроенный код выполняется в контексте сайта. Это значит, что злоумышленник получает доступ к DOM, кукам, localStorage и может, например, украсть сессию или перенаправить пользователя на фишинговую страницу.

Быстрая проверка: открыть файл в текстовом редакторе

Самый простой и доступный способ — открыть SVG как текст. Любой SVG-файл по сути — это обычный XML-документ, и его можно прочитать в Блокноте, VS Code, Sublime Text или любом другом редакторе.

  1. Найдите SVG-файл на диске.
  2. Откройте его в текстовом редакторе (правый клик → «Открыть с помощью» → ваш редактор).
  3. Просмотрите содержимое визуально или выполните поиск по ключевым словам.

Что искать:

  • <script — любой тег script
  • javascript: — протокол в ссылках
  • onload=, onclick=, onerror=, onmouseover= — обработчики событий
  • animate, animateEvent, animateTransform с атрибутом onbegin, onend
  • foreignObject — может содержать HTML с инъекцией
  • href= или xlink:href= с подозрительными URL

Если файл выглядит как обычная разметка с тегами <path>, <rect>, <circle>, <g> и ничего из приведённого выше нет — скорее всего, всё чисто. Но «скорее всего» — не гарантия, особенно если файл большой и запутанный.

Инструменты для автоматической проверки

Ручной просмотр работает для маленьких файлов, но если вы имеете дело с десятками или сотнями SVG, нужны автоматические инструменты. Вот что реально помогает.

1. Командная строка: grep и ripgrep

Если у вас есть доступ к терминалу (Linux, macOS, WSL на Windows), это самый быстрый способ массовой проверки.

Пример с grep:

grep -rE "

Или через ripgrep (быстрее на больших объёмах):

rg -i '

Команда найдёт все файлы, в которых встречается хотя бы одно из ключевых слов. Это не идеальный анализ — могут быть ложные срабатывания (например, в комментариях), но как первичный фильтр работает отлично.

2. Онлайн-сканеры SVG

Существуют веб-инструменты, которые принимают SVG-файл и проверяют его на наличие активных элементов. Они анализируют DOM-структуру и выявляют подозрительные узлы.

Что искать при выборе такого инструмента:

  • проверка на наличие <script>, обработчиков событий и внешних ссылок
  • анализ вложенных элементов и foreignObject
  • понятный отчёт: где именно найдена угроза, в какой строке
  • офлайн-режим или гарантия, что файл не сохраняется на сервере

Если вы работаете с конфиденциальными материалами, используйте только офлайн-инструменты. Загружать клиентские SVG на сторонние сайты — плохая практика.

3. Библиотеки для разработчиков

Если вы интегрируете проверку в процесс сборки или в бэкенд сайта, есть готовые библиотеки:

  • svg-sanitizer (Node.js) — основан на DOMPurify, очищает SVG от опасных элементов
  • DOMPurify — универсальный санизатор, работает и с SVG, настраивается через whitelist
  • defusedxml (Python) — библиотека для безопасного парсинга XML, в том числе SVG

Пример с DOMPurify на Node.js:

const createDOMPurify = require("dompurify");
const { JSDOM } = require("jsdom");

const window = new JSDOM("").window;
const DOMPurify = createDOMPurify(window);

const dirtySvg = '<svg><script>alert(1)</script></svg>';
const cleanSvg = DOMPurify.sanitize(dirtySvg);

console.log(cleanSvg);
// Результат: <svg></svg> — скрипт удалён

Это не просто поиск, а реальная очистка: опасные элементы удаляются, безопасная графика остаётся.

Сравнение подходов к проверке

Способ Скорость Надёжность Порог входа Для кого подходит
Открыть в редакторе Медленно (по одному файлу) Средняя — можно пропустить скрытый код Минимальный Дизайнер, контент-менеджер
grep / ripgrep Очень быстро (сотни файлов за секунды) Средняя — ищет по паттернам, не понимает структуру Нужен терминал Разработчик, DevOps
Онлайн-сканеры Быстро Высокая (если инструмент качественный) Минимальный Любой, но с оговоркой по конфиденциальности
Библиотеки (DOMPurify и др.) Мгновенно (в коде) Высокая — парсит DOM, а не просто текст Нужен навык разработки Разработчик, интеграция в CI/CD

Что делать в зависимости от ситуации

Ситуация 1: вы получили SVG от стороннего подрядчика

Не вставляйте файл на сайт, пока не проверите. Откройте в редакторе, просмотрите глазами, затем прогните через grep или онлайн-сканер. Если нашли подозрительный код — верните файл подрядчику с описанием проблемы. Нормальный дизайнер делает чистый SVG без скриптов.

Ситуация 2: вы загружаете SVG через админку сайта

Это самый опасный сценарий, потому что загруженный файл сразу становится частью вашего сайта. Настройте серверную санитизацию: при загрузке SVG пропускайте его через DOMPurify или аналог, удаляйте все скрипты и обработчики событий, сохраняйте только «безопасные» теги (<path>, <rect>, <circle>, <line>, <polygon>, <polyline>, <ellipse>, <text>, <g>, <svg>, <defs>, <use>, <clipPath>, <mask>, <style>, <title>, <desc>).

Ситуация 3: вы храните библиотеку SVG-иконок

Проведите массовую проверку всей библиотеки через ripgrep или напишите скрипт на Python/Node.js, который пройдёт по всем файлам и выдаст отчёт. После проверки настройте автоматическую санитизацию при добавлении новых иконок в библиотеку.

Ситуация 4: нужно вставить SVG на сайт и быть уверенным

Лучший подход — встроить SVG через <img src="..."> или как background-image в CSS. Браузер не выполняет JavaScript внутри SVG, загруженного через <img>. А вот <object>, <embed>, <iframe> и инлайновая вставка SVG в DOM — всё это позволяет скриптам выполняться. Если вам нужна интерактивность — используйте только проверенные файлы и санитизируйте их.

Частые ошибки при проверке SVG

Ошибка 1: «SVG — это картинка, картинки безопасны». Это заблуждение. SVG — исполняемый документ. Браузер может запускать внутри него код так же, как на HTML-странице.

Ошибка 2: проверка только тега <script>. Скрипты могут выполняться через обработчики событий (onload, onerror), через foreignObject, через animate с триггерами. Проверяйте весь спектр.

Ошибка 3: проверка «на глаз» без инструментов. Большой SVG с тысячами строк разметки невозможно просмотреть вручную. Используйте автоматические инструменты.

Ошибка 4: очистка только на клиенте. Если вы санитизируете SVG только в браузере перед вставкой в DOM, злоумышленник может обойти эту проверку. Санитизация должна происходить на сервере.

Ошибка 5: игнорирование внешних ресурсов. Даже если в самом SVG нет <script>, он может ссылаться на внешний скрипт через <script xlink:href="https://evil.com/payload.js">. Проверяйте все внешние ссылки.

Как настроить процесс, чтобы не проверять каждый файл вручную

Если SVG-файлы регулярно попадают в ваш проект, есть смыв выстроить систему, которая делает проверку автоматической:

  1. Настройте санитизацию на уровне загрузки. Каждый раз, когда файл загружается на сервер, пропускайте его через DOMPurify или аналогичную библиотеку перед сохранением.
  2. Добавьте проверку в CI/CD. Если SVG-файлы хранятся в Git, настройте pre-commit hook или pipeline-шаг, который сканирует добавленные SVG и блокирует коммит с опасным содержимым.
  3. Используйте Content Security Policy. Настройте заголовок Content-Security-Policy так, чтобы запретить выполнение инлайн-скриптов. Это страховка на случай, если что-то проскочит.
  4. Ограничьте список разрешённых тегов и атрибутов. Составьте белый список элементов SVG, которые действительно нужны в вашем проекте, и удаляйте всё остальное.

Признаки безопасного SVG-файла

Чистый, безопасный SVG обычно выглядит так:

  • Содержит только графические элементы: <path>, <rect>, <circle>, <line>, <polygon>, <polyline>, <ellipse>, <text>, <g>, <defs>, <use>, <clipPath>, <mask>, <style>, <title>, <desc>.
  • Не содержит <script>, <foreignObject>, обработчиков событий.
  • ️Не содержит внешних ссылок на ресурсы, которые вы не контролируете.
    ️Разумный размер файла: обычная иконка — от нескольких сотен байт до нескольких десятков килобайт. Если SVG весит мегабайт при простой графике — повод присмотреться.

Что в итоге

Проверка SVG на встроенный JavaScript — это не разовая акция, а часть процесса работы с файлами. Если вы просто хотите проверить один файл — откройте его в редакторе и поищите ключевые слова. Если работаете с SVG регулярно — настройте автоматическую санитизацию и добавьте проверку в пайплайн.

Главное правило: не доверяйте SVG-файлам из непроверенных источников и не вставляйте их на сайт без проверки. Формат мощный и гибкий, но эта гибкость имеет цену — и расплачивается за неё безопасность ваших пользователей.

Оцените статью
PEFile — Безопасность и технологии простым языком