Код-ревью Middle XSS и CSP обновлено

Ревью: карточка комментария на React

Вопрос

Найдите проблемы безопасности в компоненте.

export function Comment({ comment }) {
  const html = marked.parse(comment.body);
  return (
    <div className="comment">
      <a href={comment.author.website}>{comment.author.name}</a>
      <div dangerouslySetInnerHTML={{ __html: html }} />
      <img src={comment.author.avatar} onError={(e) => eval(comment.onErrorCode)} />
    </div>
  );
}

Коротко

Хранимый XSS через три разных пути. Исправление: санитизация HTML (DOMPurify), проверка схемы URL, отказ от eval.

Что должен найти ревьюер

  1. Безопасностьстрока 2
    Markdown превращается в HTML без санитизации: в Markdown можно вставить сырой HTML с <img onerror>. Нужен DOMPurify после рендера.
  2. Безопасностьстрока 5
    website пользователя без проверки схемы: javascript: URL опасен. React в зависимости от версии только предупреждает о таких URL или блокирует их, полагаться на это нельзя: проверяйте схему явно.
  3. Безопасностьстрока 6
    dangerouslySetInnerHTML с несанитизированным HTML: хранимый XSS.
  4. Безопасностьстрока 7
    eval строки из данных комментария: прямое выполнение кода атакующего.

Разбор

Хранимый XSS через три разных пути. Исправление: санитизация HTML (DOMPurify), проверка схемы URL, отказ от eval. Дополнительно строгая CSP без unsafe-eval заблокировала бы последнюю строку.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.