Безопасность фронтенда: обзор угроз и защит
Фронтенд — это точка входа в приложение, где обрабатываются формы, хранятся токены и рендерится пользовательский контент. Именно здесь происходит большинство атак: XSS, CSRF, кража секретов, эксплуатация уязвимых зависимостей. Статья даёт обзор угроз и защит для фронтенд-разработчика — карту тем с ссылками на глубокие разборы.
Содержание
- Почему фронтендеру нельзя игнорировать безопасность
- Карта угроз
- XSS — атака, которая не умирает
- CSRF — когда браузер становится оружием
- CSP — вторая линия обороны
- Секреты и аутентификация
- HTTP-заголовки и зависимости
- Философия защиты — глубокая защита и безопасность по умолчанию
- Чек-лист безопасности
- Ключевые тезисы для интервью
- Заключение
- Полезные ссылки
Почему фронтендеру нельзя игнорировать безопасность
Многие фронтенд-разработчики считают безопасность «заботой бэкенда». Это опасное заблуждение. В современном вебе фронтенд — это точка входа для пользователей, место, где обрабатываются данные форм, хранятся токены и рендерится пользовательский контент. И именно здесь происходит большинство атак.
Представьте, что ваше приложение — это банк. Бэкенд — это хранилище денег в подвале с бронированными дверями. Но фронтенд — это окно выдачи, через которое клиенты общаются с кассиром. Если окно не защищено, неважно, насколько крепки стены хранилища — грабитель может дотянуться до денег прямо через окно.
OWASP Top 10 включает несколько уязвимостей, которые напрямую связаны с фронтендом: инъекции (включая XSS), broken access control, security misconfiguration. Каждая из них может быть эксплуатирована через клиентскую часть приложения.
Карта угроз
| Угроза | Вектор | Основная защита | Разбор |
|---|---|---|---|
| XSS | Инъекция кода через ввод пользователя | Экранирование, санитизация, CSP | XSS: анатомия атаки |
| CSRF | Браузер жертвы как оружие | SameSite, CSRF-токены, Origin | CSRF: механика атаки |
| Утечка секретов | NEXT_PUBLIC_, runtimeConfig, git | Серверный прокси, vaults, hooks | Управление секретами |
| Слабая аутентификация | Кросс-сайтовые утечки токенов | HttpOnly cookies, OAuth/PKCE, RBAC | Аутентификация и авторизация |
| Отсутствие заголовков | Clickjacking, downgrade, утечка URL | Security-заголовки, CSP | HTTP-заголовки безопасности |
| Supply chain | Вредоносные пакеты, typosquatting | Lock-файлы, npm audit, SBOM | Зависимости и supply chain |
| Процессы и аудит | Compliance, incident response | Secure SDLC, access reviews | SOC2 и CASA |
XSS — атака, которая не умирает
XSS (Cross-Site Scripting) — это внедрение вредоносного JavaScript-кода в страницу, которую просматривает жертва. Существует с 1996 года и остаётся одной из самых распространённых уязвимостей, потому что каждый раз, когда приложение берёт данные от пользователя и вставляет их в HTML, создаётся потенциальная дыра.
Три основных типа:
- Отражённый (Reflected) — код приходит в URL и «отражается» от сервера в ответе.
- Хранимый (Stored) — код сохраняется в базе и показывается всем пользователям. Самый опасный тип.
- DOM-based — код выполняется на клиенте через манипуляции с DOM, без участия сервера.
React и Vue автоматически экранируют значения в JSX/интерполяциях, но защита заканчивается там, где разработчик обходит её вручную: dangerouslySetInnerHTML и v-html, javascript: URL в атрибутах, прямой доступ к DOM через refs, несанитизированные third-party библиотеки.
Глубокий разбор: XSS: анатомия атаки и методы защиты.
CSRF — когда браузер становится оружием
CSRF (Cross-Site Request Forgery) — атака, при которой злоумышленник заставляет браузер жертвы выполнить нежелательный запрос к авторизованному сайту. Злоумышленник не взламывает сервер — он использует легитимный браузер пользователя как оружие: браузер автоматически прикрепляет cookies к запросам на домен, независимо от того, какой сайт инициировал запрос.
Три линии защиты, которые дополняют друг друга:
- CSRF-токены — сервер генерирует уникальный токен, злоумышленник не может его узнать из-за Same-Origin Policy.
- SameSite cookies — браузер не отправляет cookie при cross-site запросах;
Lax— компромисс,Strict— максимальная защита. - Проверка Origin/Referer — сервер проверяет, откуда пришёл запрос; дополнительный слой, а не замена токенов.
CSRF-защита нужна даже в эпоху JSON API: злоумышленник может отправить JSON-запрос через fetch с credentials: "include".
Глубокий разбор: CSRF: механика атаки и линии защиты.
CSP — вторая линия обороны
Content Security Policy (CSP) — HTTP-заголовок, который говорит браузеру, откуда разрешено загружать скрипты, стили, изображения и другие ресурсы. CSP не заменяет экранирование, а работает как вторая линия обороны: даже если XSS-уязвимость существует, политика блокирует выполнение вредоносного кода.
Ключевые концепции:
default-src 'self'задаёт базу, от которой отталкиваются остальные директивы;'unsafe-inline'вscript-srcсводит защиту на нет — вместо него используют nonce или hash;strict-dynamicупрощает работу с бандлерами, не требуя жёсткого списка источников;Content-Security-Policy-Report-Onlyпозволяет тестировать политику без блокировки;frame-ancestors 'none'защищает от clickjacking.
Глубокий разбор: CSP: директивы и практика.
Секреты и аутентификация
Секреты
Фундаментальное правило веба: всё, что отправляется в браузер, может быть прочитано. Переменные с префиксом NEXT_PUBLIC_ (и аналогами VITE_, NUXT_PUBLIC_) встраиваются в клиентский бандл на этапе сборки. Секретные ключи должны использоваться только в серверном коде через серверный прокси, а в production — через хранилища секретов (Vault, AWS Secrets Manager, Doppler) с ротацией и аудитом доступа. Защита .env от git — через .gitignore и pre-commit hooks (gitleaks).
Глубокий разбор: Управление секретами во фронтенде.
Аутентификация и авторизация
Аутентификация отвечает на вопрос «кто ты?», авторизация — «что тебе можно?». Для SPA важно понимать компромиссы между сессиями и JWT, пару access + refresh token, OAuth 2.0 и OIDC с PKCE, и почему хранение токенов в localStorage опаснее HttpOnly cookies. Контроль доступа строится на RBAC (роли) и ABAC (атрибуты). Клиентская проверка авторизации — лишь адаптация UI, серверная валидация обязательна на каждом уровне.
Глубокий разбор: Аутентификация и авторизация во фронтенде.
HTTP-заголовки и зависимости
HTTP-заголовки
Security-заголовки закрывают целые классы атак без изменений в бизнес-логике: HSTS блокирует downgrade на HTTP, X-Frame-Options — clickjacking, X-Content-Type-Options: nosniff — MIME-sniffing, Referrer-Policy — утечку URL, COOP/COEP — cross-origin атаки, Permissions-Policy — ненужные браузерные API.
Глубокий разбор: HTTP-заголовки безопасности.
Supply chain
Современный проект имеет сотни транзитивных зависимостей, каждая из которых — чужой код, выполняемый в вашем приложении. Инциденты event-stream, ua-parser-js, colors и xz utils показали, что угроза реальна. Защита: коммитить lock-файлы, запускать npm audit в CI, использовать Snyk/Socket, составлять SBOM и проверять provenance пакетов.
Глубокий разбор: Безопасность зависимостей и supply chain.
Compliance и аудит
Для SOC2 и CASA фронтендеру важно понимать, какие controls касаются его кода, как формализуются изменения в production, из каких фаз состоит incident response и как подготовиться к penetration test.
Глубокий разбор: SOC2 и CASA для фронтенд-разработчика.
Философия защиты — глубокая защита и безопасность по умолчанию
Принцип глубокой защиты (Defense in Depth)
Не полагайтесь на одну линию защиты. Каждая защита может быть обойдена — важно, чтобы за ней была другая.
Слой 1: Middleware — проверка авторизации
↓ (если обойдён)
Слой 2: Server Component — проверка прав
↓ (если обойдён)
Слой 3: Server Action — валидация данных
↓ (если обойдена)
Слой 4: Database — constraints и проверки
↓ (если обойдены)
Слой 5: CSP — блокировка вредоносного кода
Если злоумышленник обойдёт middleware (отправив запрос напрямую), его остановит Server Action. Если обойдёт Server Action (подделав сессию), его остановит проверка прав в базе данных. Если даже он вставит вредоносный скрипт, его заблокирует CSP.
Принцип наименьших привилегий
Каждый компонент, API-эндпоинт и Server Action должны иметь минимально необходимые права. Если функция может только читать данные, она не должна иметь права на запись. Если пользователь — обычный пользователь, он не должен иметь права администратора.
Безопасность по умолчанию
Компоненты и функции должны быть безопасными по умолчанию — без необходимости явно включать защиту. Разработчик должен приложить усилия, чтобы сделать что-то опасное, а не чтобы сделать что-то безопасное.
// ✅ Компонент безопасен по умолчанию
function ExternalLink({ href, children }) {
return (
<a href={href} rel="noopener noreferrer" target="_blank">
{children}
</a>
);
}
rel="noopener noreferrer" предотвращает tabnabbing-атаку, и разработчик не должен помнить об этом — компонент уже безопасен.
Чек-лист безопасности
Перед деплоем
- Обновлены React, Next.js и все зависимости
- Проверено
npm audit/pnpm audit - Секреты не в клиентском бандле (проверить через
NEXT_PUBLIC_) - Настроены HTTP-заголовки безопасности
- Настроен CSP (хотя бы в report-only режиме)
- Server Actions валидируют входные данные
- Проверка авторизации во всех защищённых маршрутах и действиях
- CSRF-защита для критических операций
- Rate limiting для публичных API
-
.envфайлы в.gitignore - Cookie с флагами
httpOnly,secure,sameSite - Lock-файлы закоммичены в репозиторий
Регулярно
- Аудит зависимостей (еженедельно/ежемесячно)
- Ротация секретов (ежеквартально)
- Проверка CSP-отчётов
- Penetration testing (для критических приложений)
- Review зависимостей перед установкой новых пакетов
Антипаттерны — чего никогда не делать
1. Хранение секретов в клиентском коде. Если ключ попадает в бандл — он скомпрометирован. Используйте серверные прокси.
2. Игнорирование валидации. Клиентские данные — это хаос. Валидируйте всё на сервере, даже если есть валидация на клиенте.
3. Хранение токенов в localStorage. XSS может украсть localStorage. Используйте HttpOnly cookies.
4. Отсутствие rate limiting. Без rate limiting ваше API уязвимо для spam и brute-force атак.
5. Доверие параметрам URL. URL контролирует пользователь. Валидируйте все параметры маршрутов.
6. Передача лишних данных клиенту. Если клиенту не нужно поле passwordHash — не передавайте его, даже если рендерите только name.
Ключевые тезисы для интервью
- Безопасность фронтенда — не «забота бэкенда»: XSS, CSRF, кража секретов и Open Redirect эксплуатируются именно через клиент; defense in depth — middleware, серверная проверка, БД-constraints и CSP работают в связке.
- XSS бывает трёх типов — отражённый, хранимый и DOM-based; React экранирует значения в JSX, но
dangerouslySetInnerHTML,javascript:URL и прямой доступ к DOM обходят защиту; CSP — вторая линия обороны, nonce-based CSP соstrict-dynamicдаёт наиболее строгую защиту. - CSRF работает потому, что браузер автоматически прикрепляет cookies к cross-site запросам; защита строится на CSRF-токенах,
SameSitecookies и проверкеOrigin/Referer. - Server Actions выполняются на сервере, но вызываются с клиента — валидация входа (Zod), проверка авторизации и rate limiting обязательны в каждом действии.
- Переменные с префиксом
NEXT_PUBLIC_встраиваются в клиентский бандл; секретные ключи — только в серверном коде через прокси; аутентификация отвечает «кто вы», авторизация — «что вам можно», проверять нужно на middleware, Server Component и Server Action. - HTTP-заголовки (
X-Frame-Options,HSTS,Referrer-Policy,Permissions-Policy) закрывают класс атак с минимальными усилиями; lock-файлы иnpm auditв CI защищают от supply chain атак.
Заключение
Безопасность фронтенда — это не набор изолированных проверок, а системный подход. React экранирует JSX, но dangerouslySetInnerHTML открывает XSS. SameSite=Lax защищает от CSRF в большинстве случаев, но токены нужны для критических операций. Server Actions удобны, но требуют явной валидации и авторизации. CSP закрывает вредоносные скрипты, HTTP-заголовки — clickjacking, HSTS — downgrade-атаки, аудит зависимостей — supply chain. Работайте по принципу defense in depth: каждая защита может быть обойдена, но за ней должна быть следующая. И помните главное правило — никогда не доверяйте клиенту.
Полезные ссылки
- OWASP Top 10
- MDN — Web Security
- Content Security Policy Reference
- Next.js Security Headers
- XSS: анатомия атаки
- CSRF: как браузер становится оружием
- CSP: Content Security Policy
- HTTP-заголовки безопасности
- Аутентификация и авторизация
- Управление секретами
- Безопасность зависимостей и supply chain
- Подготовка к SOC2 и CASA