\"\n// React отобразит литерально текст, не выполнит скрипт\n```\n\n### Инструменты для дополнительной защиты\n\n```javascript\n// 1. DOMPurify - удаляет опасный HTML\nimport DOMPurify from 'dompurify';\nconst clean = DOMPurify.sanitize(userInput);\n\n// 2. Markdown с ограничениями\nimport { marked } from 'marked';\nconst html = marked(userInput, { breaks: true });\nconst clean = DOMPurify.sanitize(html);\n\n// 3. Валидация URL\nfunction isValidUrl(url) {\n try {\n const parsed = new URL(url);\n return ['http:', 'https:', 'mailto:', '/'].includes(parsed.protocol);\n } catch {\n return false;\n }\n}\n\n// 4. Content Security Policy (CSP)\n// В HTML head\n\n```\n\n### Checklist безопасности для Frontend Developer\n\n- ✅ React автоматически экранирует текст в JSX\n- ❌ Не используй dangerouslySetInnerHTML без санитизации\n- ✅ React блокирует javascript: протоколы в href\n- ❌ Не доверяй данным от пользователей\n- ✅ Используй библиотеки вроде DOMPurify для HTML\n- ✅ Устанавливай Content-Security-Policy заголовки\n- ❌ Не вставляй пользовательский код в onclick и другие обработчики\n- ✅ Валидируй все входные данные\n\n### Выводы\n\n**React защищает от XSS по умолчанию через:**\n1. Экранирование текста в JSX\n2. Преобразование JSX в функции (не в строки)\n3. Блокирование опасных протоколов (javascript:)\n4. Требование явного использования dangerouslySetInnerHTML\n\n**Твоя ответственность:**\n- Никогда не используй dangerouslySetInnerHTML без санитизации\n- Валидируй пользовательский ввод\n- Используй санитизирующие библиотеки для HTML контента\n- Следи за Content-Security-Policy\n\nReact — это **безопасный по умолчанию** фреймворк, но ты должен понимать ограничения и использовать дополнительные инструменты где нужно.","dateCreated":"2026-04-02T22:21:16.213794","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как React защищает от XSS?

1.8 Middle🔥 301 комментариев
#React#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как React защищает от XSS?

XSS (Cross-Site Scripting) — это атака, когда вредоносный код (обычно JavaScript) внедряется на веб-сайт и выполняется в браузере пользователя. React имеет встроенные механизмы защиты от этого.

Что такое XSS?

// Пример уязвимости
const userInput = '<img src=x onerror="alert(\"Hacked!\")">'; // Опасные данные от пользователя

// В обычном HTML/jQuery
document.innerHTML = userInput; // Выполнит JavaScript!

// Результат: попап "Hacked!" - атака сработала

Как React защищает

1. Экранирование (Escaping) - главная защита

React по умолчанию экранирует все текстовые данные в JSX:

const userInput = '<img src=x onerror="alert(\"Hacked!\")">'; // XSS попытка

function Component() {
  return <div>{userInput}</div>; // Безопасно!
}

// React отобразит буквальный текст:
// <div>&lt;img src=x onerror="alert(\"Hacked!\")"&gt;</div>
// XSS не выполнится!

Как работает экранирование:

Опасные символы -> Экранированы
< -> &lt;
> -> &gt;
" -> &quot;
' -> &#x27;
& -> &amp;

Браузер отображает экранированный текст как обычный текст, а не как HTML.

2. JSX преобразует в функции

JSX не выполняет произвольный код, а преобразует в функции React:

// JSX
<div className="hello">{message}</div>

// После преобразования
React.createElement('div', { className: 'hello' }, message);

// React проверяет типы и экранирует

3. Специальные атрибуты требуют осторожности

Данные в атрибутах требуют осторожности. React проверяет некоторые из них:

const userInput = 'javascript:alert("XSS")';

// ❌ Опасно
<a href={userInput}>Link</a>

// ✅ React блокирует javascript: протоколы
// Вывод: href="" (атрибут игнорируется)

// Протоколы, которые React блокирует:
// javascript:
// data: (в некоторых контекстах)
// vbscript:

Уязвимые паттерны (когда React НЕ защищает)

1. dangerouslySetInnerHTML

Этот метод специально создан для вставки HTML, поэтому ответственность на тебе:

// ❌ ОЧЕНЬ ОПАСНО!
const userInput = '<img src=x onerror="alert(\"Hacked!\")">'; // От пользователя

function Component() {
  return (
    <div
      dangerouslySetInnerHTML={{ __html: userInput }}
    />
  );
}
// XSS сработает!

// ✅ Только для доверенного контента
const trustedHTML = '<b>Bold text</b>'; // Ты сам написал

function Component() {
  return <div dangerouslySetInnerHTML={{ __html: trustedHTML }} />;
}

Когда использовать dangerouslySetInnerHTML:

  • Очень редко
  • Только для контента, которому ты доверяешь
  • Всегда санитизируй входные данные (используй библиотеки)
import DOMPurify from 'dompurify';

const userInput = '<img src=x onerror="alert(\"Hacked!\")">'; // Опасные данные

function Component() {
  const cleanHTML = DOMPurify.sanitize(userInput); // Очищаем

  return <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />;
}

// DOMPurify удалит опасный onerror обработчик
// Результат: <img src="x">

2. Атрибуты event handlers

Опасно интерполировать строки в обработчики событий:

// ❌ Неправильно
const handler = userInput; // Может содержать код
return <button onClick={handler}>Click</button>; // Опасно!

// ✅ Правильно
const handleClick = () => {
  // Твой код
};
return <button onClick={handleClick}>Click</button>;

3. Динамические style

Опасно вставлять пользовательские стили:

// ❌ Опасно (хотя обычно безопасно из-за CSS синтаксиса)
const style = userInput; // expression: alert(1)
return <div style={style}>Content</div>;

// ✅ Правильно
const style = { color: 'red', fontSize: '14px' };
return <div style={style}>Content</div>;

Практические примеры защиты

Пример 1: Комментарии пользователей

import DOMPurify from 'dompurify';

function CommentList({ comments }) {
  return (
    <ul>
      {comments.map(comment => (
        <li key={comment.id}>
          <strong>{comment.author}</strong>
          {/* Безопасно - React экранирует */}
          <p>{comment.text}</p>
        </li>
      ))}
    </ul>
  );
}

// Если нужен HTML (форматирование):
function FormattedCommentList({ comments }) {
  return (
    <ul>
      {comments.map(comment => (
        <li key={comment.id}>
          <strong>{comment.author}</strong>
          {/* Санитизируем перед вставкой */}
          <div
            dangerouslySetInnerHTML={{
              __html: DOMPurify.sanitize(comment.htmlContent)
            }}
          />
        </li>
      ))}
    </ul>
  );
}

Пример 2: Ссылки

function LinkComponent({ url, label }) {
  // React блокирует javascript: протоколы
  return <a href={url}>{label}</a>;
}

// Использование
<LinkComponent 
  url="javascript:alert('XSS')" // Безопасно - React проигнорирует
  label="Click"
/>

// Дополнительная проверка (рекомендуется)
function SafeLink({ url, label }) {
  // Проверяем протокол
  const isValidUrl = url && (url.startsWith('/') || url.startsWith('http'));
  
  return (
    <a href={isValidUrl ? url : '#'}>
      {label}
    </a>
  );
}

Пример 3: Поиск (динамический контент)

function SearchResults({ query, results }) {
  return (
    <div>
      {/* Безопасно - React экранирует query */}
      <p>Результаты для: <strong>{query}</strong></p>
      
      <ul>
        {results.map(result => (
          <li key={result.id}>
            {/* Безопасно */}
            <a href={result.url}>{result.title}</a>
            <p>{result.description}</p>
          </li>
        ))}
      </ul>
    </div>
  );
}

// Даже если query = "<script>alert('XSS')</script>"
// React отобразит литерально текст, не выполнит скрипт

Инструменты для дополнительной защиты

// 1. DOMPurify - удаляет опасный HTML
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(userInput);

// 2. Markdown с ограничениями
import { marked } from 'marked';
const html = marked(userInput, { breaks: true });
const clean = DOMPurify.sanitize(html);

// 3. Валидация URL
function isValidUrl(url) {
  try {
    const parsed = new URL(url);
    return ['http:', 'https:', 'mailto:', '/'].includes(parsed.protocol);
  } catch {
    return false;
  }
}

// 4. Content Security Policy (CSP)
// В HTML head
<meta
  http-equiv="Content-Security-Policy"
  content="default-src 'self'; script-src 'self' 'unsafe-inline'"
/>

Checklist безопасности для Frontend Developer

  • ✅ React автоматически экранирует текст в JSX
  • ❌ Не используй dangerouslySetInnerHTML без санитизации
  • ✅ React блокирует javascript: протоколы в href
  • ❌ Не доверяй данным от пользователей
  • ✅ Используй библиотеки вроде DOMPurify для HTML
  • ✅ Устанавливай Content-Security-Policy заголовки
  • ❌ Не вставляй пользовательский код в onclick и другие обработчики
  • ✅ Валидируй все входные данные

Выводы

React защищает от XSS по умолчанию через:

  1. Экранирование текста в JSX
  2. Преобразование JSX в функции (не в строки)
  3. Блокирование опасных протоколов (javascript:)
  4. Требование явного использования dangerouslySetInnerHTML

Твоя ответственность:

  • Никогда не используй dangerouslySetInnerHTML без санитизации
  • Валидируй пользовательский ввод
  • Используй санитизирующие библиотеки для HTML контента
  • Следи за Content-Security-Policy

React — это безопасный по умолчанию фреймворк, но ты должен понимать ограничения и использовать дополнительные инструменты где нужно.

Как React защищает от XSS? | PrepBro