← Назад к вопросам

Как бороться с уязвимостями внутри браузеров?

2.0 Middle🔥 181 комментариев
#JavaScript Core

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

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

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

Как бороться с уязвимостями внутри браузеров

Браузер — это окно в интернет, и с ним приходят безопасные и опасные возможности. На фронтенде есть несколько основных уязвимостей и способы их предотвращения.

Основные веб-уязвимости

1. XSS (Cross-Site Scripting)

Суть: Злоумышленник вводит вредоносный JavaScript код в вашу страницу.

Пример уязвимости:

// ПЛОХО: использование innerHTML с пользовательским вводом
const userInput = '<img src="x" onerror="alert(\"Hacked!\")">'; 
document.getElementById('container').innerHTML = userInput;
// Код выполнится!

Защита: использовать textContent вместо innerHTML

// ХОРОШО: textContent безопасен
const userInput = '<img src="x" onerror="alert(\"Hacked!\")">'; 
const div = document.createElement('div');
div.textContent = userInput; // Просто текст, не код
document.getElementById('container').appendChild(div);

Защита: использовать DOMPurify для очистки HTML

import DOMPurify from 'dompurify';

const userInput = '<img src="x" onerror="alert(\"Hacked!\")">'; 
const clean = DOMPurify.sanitize(userInput);
document.getElementById('container').innerHTML = clean;
// Результат: <img src="x"> — без onerror

Защита: Content Security Policy (CSP)

<!-- В заголовке HTTP ответа -->
Content-Security-Policy: script-src 'self' https://trusted-cdn.com

<!-- Или в метатеге -->
<meta http-equiv="Content-Security-Policy" 
      content="script-src 'self'">

CSP говорит браузеру: "Выполняй скрипты только с источника 'self' и https://trusted-cdn.com. Все остальное блокируй".

2. CSRF (Cross-Site Request Forgery)

Суть: Враг заставляет вас выполнить действие на другом сайте без вашего согласия.

Пример уязвимости:

<!-- На вредоносном сайте -->
<img src="https://bank.com/transfer?to=attacker&amount=1000">
<!-- Если вы залогинены в банке, перевод пройдёт! -->

Защита: CSRF токены

// Сервер генерирует уникальный токен для каждой формы
const form = document.querySelector('form');
const token = form.querySelector('input[name=csrf_token]').value;

// При отправке, включаем токен
fetch('/api/transfer', {
  method: 'POST',
  headers: {
    'X-CSRF-Token': token,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({to: 'alice', amount: 100})
});

Сервер проверяет: если токен верный — выполняем, если нет — отклоняем.

Защита: SameSite cookies

Set-Cookie: sessionId=abc123; SameSite=Strict

Este флаг говорит браузеру: "Отправляй эту cookie только если запрос с того же сайта".

3. Man-in-the-Middle (MITM)

Суть: Злоумышленник перехватывает вашу сессию и выдаёт себя за сервер.

Защита: HTTPS

// ПЛОХО: HTTP не шифрует данные
http://api.example.com/api/users

// ХОРОШО: HTTPS шифрует
https://api.example.com/api/users

HTTPS использует SSL/TLS сертификаты для шифрования данных между браузером и сервером.

4. localStorage/sessionStorage уязвимости

Суть: XSS атака может украсть токены из localStorage.

Пример:

// Если есть XSS, то:
const token = localStorage.getItem('authToken');
console.log(token); // Украли!

Защита: HttpOnly cookies

Set-Cookie: authToken=abc123; HttpOnly; Secure; SameSite=Strict

HttpOnly флаг запрещает JavaScript доступ к cookie. Браузер автоматически отправляет её в запросах, но код не может украсть.

// Это НЕ сработает
const token = document.cookie; // Не видит HttpOnly cookies

5. Clickjacking

Суть: Враг подменяет видимые элементы скрытыми элементами, заставляя вас кликать на невидимые кнопки.

Пример:

<!-- Вредоносный сайт -->
<button>"Click for prize!"</button>

<!-- Но на самом деле сверху лежит невидимая рамка с кнопкой удалить аккаунт -->
<iframe src="https://bank.com/delete-account" 
        style="opacity: 0; position: absolute; width: 100%; height: 100%;">
</iframe>

Защита: X-Frame-Options header

X-Frame-Options: DENY  /* Запрещает iframe вообще */
X-Frame-Options: SAMEORIGIN  /* Разрешает только с того же сайта */

Чеклист безопасности фронтенда

1. Валидация входных данных

// ПЛОХО
const data = userInput;

// ХОРОШО
const data = validator.escape(userInput);
const data = validator.isEmail(userInput) ? userInput : null;

2. Используй фреймворки с встроенной защитой

// React автоматически экранирует значения
<div>{userInput}</div>  // Безопасно по умолчанию

// Опасно только если явно использовать dangerouslySetInnerHTML
<div dangerouslySetInnerHTML={{__html: userInput}} />  // Опасно!

3. Никогда не доверяй пользовательскому вводу

// ПЛОХО: eval() с пользовательским кодом
eval(userCode);

// Даже JSON.parse() может быть опасен
const data = JSON.parse(userInput); // Может быть протип-поллюция

4. Используй HTTPS везде

  • Все коммуникации должны быть encrypted
  • Certificate pinning для мобильных приложений

5. Защищай sensitive данные

// ПЛОХО: хранить токены в localStorage
localStorage.setItem('authToken', token);

// ХОРОШО: использовать HttpOnly cookies
// Сервер отправляет: Set-Cookie: authToken=...; HttpOnly

6. Логирование и мониторинг

// Отслеживай попытки XSS
try {
  // Risky operation
} catch (e) {
  logSecurityEvent('Potential XSS attempt', {error: e});
}

Примеры в React

// ПЛОХО
function BadComponent({userBio}) {
  return <div dangerouslySetInnerHTML={{__html: userBio}} />;
}

// ХОРОШО
function GoodComponent({userBio}) {
  return <div>{userBio}</div>;  // Автоматически экранирует
}

// ХОРОШО с HTML
import DOMPurify from 'dompurify';

function SafeHTML({html}) {
  const clean = DOMPurify.sanitize(html);
  return <div dangerouslySetInnerHTML={{__html: clean}} />;
}

Вывод

Безопасность — это постоянная бдительность, а не единовременная задача. На собеседовании это показывает, что вы:

  • Понимаете угрозы
  • Знаете как их предотвращать
  • Думаете о безопасности приложения
Как бороться с уязвимостями внутри браузеров? | PrepBro