\"\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"}},"suggestedAnswer":[{"@type":"Answer","text":"## Как React защищает от XSS?\n\n**XSS (Cross-Site Scripting)** — это атака, когда вредоносный код (обычно JavaScript) внедряется на веб-сайт и выполняется в браузере пользователя. React имеет встроенные механизмы защиты от этого.\n\n### Что такое XSS?\n\n```javascript\n// Пример уязвимости\nconst userInput = ''; // Опасные данные от пользователя\n\n// В обычном HTML/jQuery\ndocument.innerHTML = userInput; // Выполнит JavaScript!\n\n// Результат: попап \"Hacked!\" - атака сработала\n```\n\n### Как React защищает\n\n#### 1. Экранирование (Escaping) - главная защита\n\nReact по умолчанию экранирует все текстовые данные в JSX:\n\n```javascript\nconst userInput = ''; // XSS попытка\n\nfunction Component() {\n return
{userInput}
; // Безопасно!\n}\n\n// React отобразит буквальный текст:\n//
<img src=x onerror=\"alert(\\\"Hacked!\\\")\">
\n// XSS не выполнится!\n```\n\n**Как работает экранирование:**\n\n```\nОпасные символы -> Экранированы\n< -> <\n> -> >\n\" -> "\n' -> '\n& -> &\n```\n\nБраузер отображает экранированный текст как обычный текст, а не как HTML.\n\n#### 2. JSX преобразует в функции\n\nJSX не выполняет произвольный код, а преобразует в функции React:\n\n```javascript\n// JSX\n
{message}
\n\n// После преобразования\nReact.createElement('div', { className: 'hello' }, message);\n\n// React проверяет типы и экранирует\n```\n\n#### 3. Специальные атрибуты требуют осторожности\n\nДанные в атрибутах требуют осторожности. React проверяет некоторые из них:\n\n```javascript\nconst userInput = 'javascript:alert(\"XSS\")';\n\n// ❌ Опасно\nLink\n\n// ✅ React блокирует javascript: протоколы\n// Вывод: href=\"\" (атрибут игнорируется)\n\n// Протоколы, которые React блокирует:\n// javascript:\n// data: (в некоторых контекстах)\n// vbscript:\n```\n\n### Уязвимые паттерны (когда React НЕ защищает)\n\n#### 1. dangerouslySetInnerHTML\n\nЭтот метод специально создан для вставки HTML, поэтому ответственность на тебе:\n\n```javascript\n// ❌ ОЧЕНЬ ОПАСНО!\nconst userInput = ''; // От пользователя\n\nfunction Component() {\n return (\n \n );\n}\n// XSS сработает!\n\n// ✅ Только для доверенного контента\nconst trustedHTML = 'Bold text'; // Ты сам написал\n\nfunction Component() {\n return
;\n}\n```\n\n**Когда использовать dangerouslySetInnerHTML:**\n- Очень редко\n- Только для контента, которому ты доверяешь\n- Всегда санитизируй входные данные (используй библиотеки)\n\n```javascript\nimport DOMPurify from 'dompurify';\n\nconst userInput = ''; // Опасные данные\n\nfunction Component() {\n const cleanHTML = DOMPurify.sanitize(userInput); // Очищаем\n\n return
;\n}\n\n// DOMPurify удалит опасный onerror обработчик\n// Результат: \n```\n\n#### 2. Атрибуты event handlers\n\nОпасно интерполировать строки в обработчики событий:\n\n```javascript\n// ❌ Неправильно\nconst handler = userInput; // Может содержать код\nreturn ; // Опасно!\n\n// ✅ Правильно\nconst handleClick = () => {\n // Твой код\n};\nreturn ;\n```\n\n#### 3. Динамические style\n\nОпасно вставлять пользовательские стили:\n\n```javascript\n// ❌ Опасно (хотя обычно безопасно из-за CSS синтаксиса)\nconst style = userInput; // expression: alert(1)\nreturn
Content
;\n\n// ✅ Правильно\nconst style = { color: 'red', fontSize: '14px' };\nreturn
Content
;\n```\n\n### Практические примеры защиты\n\n#### Пример 1: Комментарии пользователей\n\n```javascript\nimport DOMPurify from 'dompurify';\n\nfunction CommentList({ comments }) {\n return (\n
    \n {comments.map(comment => (\n
  • \n {comment.author}\n {/* Безопасно - React экранирует */}\n

    {comment.text}

    \n
  • \n ))}\n
\n );\n}\n\n// Если нужен HTML (форматирование):\nfunction FormattedCommentList({ comments }) {\n return (\n
    \n {comments.map(comment => (\n
  • \n {comment.author}\n {/* Санитизируем перед вставкой */}\n \n
  • \n ))}\n
\n );\n}\n```\n\n#### Пример 2: Ссылки\n\n```javascript\nfunction LinkComponent({ url, label }) {\n // React блокирует javascript: протоколы\n return {label};\n}\n\n// Использование\n\n\n// Дополнительная проверка (рекомендуется)\nfunction SafeLink({ url, label }) {\n // Проверяем протокол\n const isValidUrl = url && (url.startsWith('/') || url.startsWith('http'));\n \n return (\n \n {label}\n \n );\n}\n```\n\n#### Пример 3: Поиск (динамический контент)\n\n```javascript\nfunction SearchResults({ query, results }) {\n return (\n
\n {/* Безопасно - React экранирует query */}\n

Результаты для: {query}

\n \n
    \n {results.map(result => (\n
  • \n {/* Безопасно */}\n {result.title}\n

    {result.description}

    \n
  • \n ))}\n
\n
\n );\n}\n\n// Даже если query = \"\"\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 комментариев

Комментарии (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 — это безопасный по умолчанию фреймворк, но ты должен понимать ограничения и использовать дополнительные инструменты где нужно.