Как бороться с уязвимостями внутри браузеров?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как бороться с уязвимостями внутри браузеров
Браузер — это окно в интернет, и с ним приходят безопасные и опасные возможности. На фронтенде есть несколько основных уязвимостей и способы их предотвращения.
Основные веб-уязвимости
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}} />;
}
Вывод
Безопасность — это постоянная бдительность, а не единовременная задача. На собеседовании это показывает, что вы:
- Понимаете угрозы
- Знаете как их предотвращать
- Думаете о безопасности приложения