Все уроки
БезопасностьСредний15 мин чтенияВ моём стеке

Веб-безопасность и OWASP Top 10

Самые распространённые веб-уязвимости с реальными примерами и защиты, которые действительно работают.

  • OWASP Top 10
  • XSS / CSRF / SQLi
  • Secrets
  • Rate limiting
  • Audits
Шаг 1/5
Форма входа. Вместо имени хакер вводит ' OR 1=1 -- и улыбается из-под тёмных очков.

За 30 секунд

OWASP Top 10 — широко используемый список самых критичных рисков безопасности веб-приложений; текущая редакция — 2025 года. Большинство реальных взломов происходят из-за короткого списка ошибок: отсутствующих проверок доступа, инъекций, ошибок конфигурации, уязвимых зависимостей и утёкших секретов. Хорошая безопасность — это набор привычек, встроенных в проектирование, код-ревью, конфигурацию и деплой, а не финальный аудит.

Почему я это использую

  • Я использую OWASP Top 10 как чек-лист, потому что он покрывает ошибки, которые на самом деле приводят к взломам бизнес-приложений.
  • Продукты, которые я строю, работают с платежами, персональными данными и данными tenant'ов, где один баг в контроле доступа превращается в серьёзный инцидент.
  • Безопасные настройки по умолчанию во фреймворках, заголовках и на серверах почти бесплатно предотвращают целые классы багов.
  • Клиенты и аудиторы всё чаще спрашивают, как устроена безопасность, и ясный, конкретный ответ укрепляет доверие.

Как это работает

01OWASP Top 10 простыми словами

OWASP (Open Worldwide Application Security Project) публикует Top 10 на основе реальных данных об уязвимостях и опросов сообщества. Редакция 2025 года выглядит так: A01 Broken Access Control (пользователи получают доступ к данным или действиям, к которым не должны; SSRF теперь входит в эту категорию); A02 Security Misconfiguration; A03 Software Supply Chain Failures (уязвимые или скомпрометированные зависимости, инструменты сборки и пайплайны); A04 Cryptographic Failures; A05 Injection (SQL, команды, а также XSS); A06 Insecure Design; A07 Authentication Failures; A08 Software or Data Integrity Failures; A09 Security Logging and Alerting Failures; A10 Mishandling of Exceptional Conditions (ошибки, при которых система «открывается» или раскрывает детали). Используйте его для повышения осведомлённости и как чек-лист для ревью, а не как полный стандарт; за детальными требованиями обращайтесь к OWASP Application Security Verification Standard (ASVS) и API Security Top 10 — они идут глубже.

02Broken access control, SSRF и CSRF

Broken access control — самый распространённый серьёзный дефект. Классический пример: GET /api/orders/1043 возвращает любой заказ, потому что код проверяет, что пользователь вошёл в систему, но не что заказ принадлежит ему. Это называется IDOR (insecure direct object reference). Решение — проверять владение или права на каждый запрос на сервере, в идеале через централизованные политики, запрещать по умолчанию и возвращать 404 для объектов, которые пользователю видеть нельзя. Server-side request forgery (SSRF) случается, когда ваш сервер загружает URL, переданный пользователем, например при импорте изображения, а атакующий направляет его на внутренние адреса или эндпоинты облачных метаданных. Разрешайте хосты и схемы по allow-list, резолвьте адреса и блокируйте приватные диапазоны IP, отключайте редиректы. Cross-site request forgery (CSRF) заставляет браузер залогиненного пользователя отправить запрос, меняющий состояние; защищайтесь cookie с SameSite, CSRF-токенами и проверкой заголовка Origin.

  • Авторизуйте каждый доступ к объекту на сервере, а не в UI.
  • Запрещайте по умолчанию; тестируйте со вторым пользовательским аккаунтом.
  • Для загрузки по URL: allow-list, блокировка приватных диапазонов, никаких редиректов.

03Инъекции и XSS

Инъекция происходит, когда пользовательский ввод воспринимается как код. При SQL-инъекции поле поиска, содержащее ' OR 1=1 --, меняет смысл запроса, собранного конкатенацией строк, что приводит к утечке или удалению данных. Решение — параметризованные запросы, где данные передаются отдельно от SQL; их поддерживает любой современный драйвер и ORM. Будьте осторожны с хелперами для сырых запросов и динамическими именами колонок — им нужны allow-list'ы. Тот же принцип применим к командам оболочки, LDAP и шаблонизаторам. Cross-site scripting (XSS) — это инъекция в HTML: атакующий сохраняет скрипт в отзыве или имени профиля, и он выполняется в браузерах других пользователей, крадя сессии или совершая действия. Фреймворки вроде React по умолчанию экранируют вывод; опасные зоны — dangerouslySetInnerHTML, v-html, неэкранированный вывод в Blade и URL в атрибутах href. Санитизируйте rich HTML проверенной библиотекой и добавьте Content Security Policy как второй слой.

ts
import { Pool } from "pg";
const db = new Pool();
 
// Vulnerable: input becomes part of the SQL text
// db.query("SELECT * FROM users WHERE email = '" + email + "'");
 
// Safe: input is sent as a parameter, never parsed as SQL
export async function findUser(email: string) {
  const { rows } = await db.query(
    "SELECT id, email FROM users WHERE email = $1",
    [email],
  );
  return rows[0] ?? null;
}

04Ошибки конфигурации и безопасные заголовки

Многим взломам не нужен хитрый эксплойт: оставленный в продакшене режим отладки, публичный бакет хранилища, пароли администратора по умолчанию, подробные страницы ошибок со стектрейсами, листинг директорий, открытые .env или папка .git, порт базы, открытый в интернет. Предотвращайте это конфигурацией в виде кода, настройками для каждого окружения и проверками в пайплайне деплоя. Заголовки безопасности добавляют защиту на стороне браузера. HTTP Strict Transport Security принудительно включает HTTPS. Content Security Policy (CSP) говорит браузеру, из каких источников разрешены скрипты, стили и изображения, и это блокирует большинство внедрённых скриптов; начните в режиме report-only, затем включите принудительно и предпочитайте nonce или хэши вместо 'unsafe-inline'. X-Content-Type-Options останавливает MIME sniffing, frame-ancestors в CSP предотвращает clickjacking, а Referrer-Policy и Permissions-Policy ограничивают, что утекает и что разрешено. Помечайте cookie как Secure, HttpOnly и SameSite.

nginx
# nginx: baseline security headers (adapt CSP sources to your app)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data: https://cdn.example.com; object-src 'none'; base-uri 'self'; frame-ancestors 'none'" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
server_tokens off;

05Секреты, зависимости и цепочка поставок

Секретам (API-ключам, паролям к базе, ключам подписи) место в переменных окружения или менеджере секретов, но никогда — в репозитории, клиентских бандлах, логах или сообщениях об ошибках. Давайте каждому секрету минимально необходимые права, разделяйте их по окружениям и ротируйте по расписанию и сразу же после любой подозрительной утечки; утёкший ключ, который нельзя быстро ротировать, — это дефект дизайна. Добавьте сканирование секретов в репозиторий и CI, чтобы ошибки ловились до push'а. Современные приложения в основном состоят из стороннего кода, поэтому сбои цепочки поставок теперь в первой тройке. Коммитьте lockfile'ы, проводите аудит зависимостей (npm audit, composer audit, Dependabot или Renovate), фиксируйте и ревьюйте CI action'ы, удаляйте неиспользуемые пакеты и с подозрением относитесь к новым пакетам с крошечным числом загрузок или install-скриптами. Держите фреймворки и рантаймы на поддерживаемых версиях.

06Rate limiting, боты, ревью и пентесты

Каждому эндпоинту, которым можно злоупотребить, нужны лимиты: вход, запросы OTP и сброса пароля, поиск, контактные формы, загрузка файлов и публичные API. Ограничивайте частоту по пользователю, IP и API-ключу, со строгими лимитами на аутентификацию; блокируйте или замедляйте аккаунты после повторных неудач и добавляйте CAPTCHA или proof-of-work только там, где злоупотребления реальны. CDN или WAF впереди поглощает объёмные атаки и блокирует известные вредоносные шаблоны. Загрузки требуют отдельного внимания: проверяйте тип по содержимому, а не по расширению, ограничивайте размер, защищайтесь от decompression bomb'ов и отдавайте файлы с отдельного домена или через подписанные ссылки. А затем сделайте безопасность процессом. Проводите threat modeling новых фич («что здесь мог бы сделать злонамеренный tenant?»), включайте пункты о безопасности в код-ревью, запускайте SAST и сканирование зависимостей в CI и заказывайте внешний пентест перед крупными запусками и периодически, исправляя находки по степени серьёзности.

  • Строгие лимиты на вход, OTP и сброс пароля.
  • Логируйте события безопасности (неудачные входы, отказы в доступе) и алертите на всплески.
  • Пентесты находят то, что вы пропустили, но не заменяют безопасных привычек.

Когда применять

  • Всегда: каждому веб-приложению и API эти основы нужны с первого релиза.
  • Перед запуском фич, которые касаются платежей, персональных данных, загрузок или прав доступа.
  • Во время код-ревью и архитектурного ревью новых эндпоинтов.
  • Перед внешними аудитами, корпоративными продажами и оценками соответствия.

Когда не стоит

  • Не считайте Top 10 полным стандартом; для детальных требований используйте ASVS.
  • Не полагайтесь на сокрытие (скрытые URL, отключённая introspection) как на единственную защиту.
  • Не изобретайте собственную криптографию или хэширование паролей; используйте проверенные библиотеки.

Альтернативы

  • OWASP ASVS

    Подробный многоуровневый чек-лист требований безопасности для проверки.

  • OWASP API Security Top 10

    Сфокусирован на рисках API, таких как авторизация на уровне объектов и потребление ресурсов.

  • Управляемый WAF и защита от ботов

    Защита на edge, которая блокирует распространённые атаки и вредоносный трафик ещё до того, как он дойдёт до вас.

  • Программы bug bounty

    Непрерывное внешнее тестирование; лучше всего — после того, как сделаны основы и пентест.

Лучшие практики

  1. Проверяйте авторизацию на сервере для каждого объекта и действия, запрещая по умолчанию.
  2. Используйте параметризованные запросы и экранирование фреймворка; санитизируйте любой rich HTML.
  3. Отправляйте заголовки безопасности, включая принудительную Content Security Policy.
  4. Держите секреты вне кода, давайте им минимальные права и ротируйте их.
  5. Автоматизируйте сканирование зависимостей и секретов в CI и держите рантаймы на поддерживаемых версиях.
  6. Ограничивайте частоту для аутентификации, OTP и эндпоинтов, которыми легко злоупотребить.
  7. Логируйте события безопасности и проверяйте свою защиту ревью и пентестами.

Частые ошибки

  • Прятать кнопку в UI вместо того, чтобы проверять права на сервере.
  • Собирать SQL или команды оболочки конкатенацией строк.
  • Оставлять в продакшене открытыми режим отладки, стектрейсы или админ-панели.
  • Закоммитить секреты в Git и лишь удалить их в одном из следующих коммитов.
  • Игнорировать алерты о зависимостях, пока активно эксплуатируемая уязвимость не вызовет аврал.

Глубже

07Пароли, сессии и токены — как положено

Храните пароли с медленным memory-hard хэшем. Password Storage Cheat Sheet от OWASP рекомендует Argon2id минимум с 19 MiB памяти, 2 итерациями и parallelism 1; scrypt — если Argon2id недоступен; bcrypt — только для legacy-систем, с work factor 10 или выше и с учётом ограничения входа в 72 байта. Проверяйте новые пароли по спискам известных утечек, а не навязывайте странные правила состава. Для сессий непрозрачные случайные ID, хранящиеся на сервере, просты и мгновенно отзываемы. Если используете JWT, фиксируйте допустимый алгоритм на сервере (никогда не доверяйте заголовку alg из токена), проверяйте issuer, audience и срок действия, делайте access-токены короткоживущими и ротируйте refresh-токены при каждом использовании, считая повторное использование старого refresh-токена кражей и отзывая всё «семейство». Перевыпускайте ID сессии после логина и смены привилегий, чтобы предотвратить session fixation.

ts
import argon2 from "argon2";
 
// OWASP minimum: Argon2id, 19 MiB memory, 2 iterations, parallelism 1
export function hashPassword(password: string) {
  return argon2.hash(password, {
    type: argon2.argon2id,
    memoryCost: 19456, // KiB
    timeCost: 2,
    parallelism: 1,
  });
}
 
export function verifyPassword(hash: string, password: string) {
  return argon2.verify(hash, password); // parameters are read from the hash
}

08Строгая Content Security Policy и Trusted Types

Политики на allow-list (script-src с множеством CDN-хостов) часто обходятся, потому что один из разрешённых хостов может отдавать JSONP-эндпоинт или старую библиотеку, которой злоумышленник может злоупотребить. Строгая политика опирается на nonce или хэши: сервер генерирует новый случайный nonce для каждого ответа и ставит его на каждый легитимный тег script и в заголовок. Добавление 'strict-dynamic' позволяет выполняться и скриптам, загруженным доверенным скриптом, так что tag manager и бандлеры продолжают работать, а внедрённая разметка без nonce блокируется. Сочетайте это с object-src 'none' и base-uri 'none' или 'self'. Против DOM-based XSS Trusted Types (require-trusted-types-for 'script') заставляет браузер отклонять сырые строки в опасных sink вроде innerHTML и пропускать код через проверенную политику санитизации. Сначала выкатывайте в режиме report-only и исправляйте нарушения.

http
Content-Security-Policy:
  script-src 'nonce-r4nd0mBase64Value' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';
  frame-ancestors 'none';
  require-trusted-types-for 'script';
  report-to csp-endpoint

09SSRF в деталях: DNS rebinding и облачные метаданные

Блокировать приватные IP в строке URL недостаточно. Злоумышленники используют альтернативные записи (десятичные или IPv6-mapped адреса), редиректы на внутренние хосты и DNS rebinding, когда hostname во время вашей проверки резолвится в публичный IP, а мгновением позже при подключении — в 127.0.0.1 или 169.254.169.254. Надёжная защита резолвит hostname один раз, проверяет каждый полученный адрес по запрещённым диапазонам (loopback, private, link-local, unique local IPv6), затем подключается именно к этому IP, отправляя исходный заголовок Host, и перепроверяет при каждом редиректе либо отключает редиректы. Ещё лучше — пропускать все запросы, инициированные пользователем, через egress-прокси, который централизованно применяет политику и не имеет доступа к внутренним сетям. В AWS требуйте IMDSv2: его session token нужно получать PUT-запросом, что блокирует большинство простых попыток SSRF против учётных данных инстанса.

  • Проверяйте резолвленные IP, а не текст URL; привязывайте подключение к ним.
  • Блокируйте loopback, RFC 1918, link-local и IPv6 unique-local диапазоны.
  • Пропускайте пользовательские запросы через изолированный egress-прокси.

10Cookie, CORS и изоляция в браузере

Атрибуты cookie — дешёвый и сильный слой. Secure и HttpOnly держат сессионные cookie подальше от обычного HTTP и от JavaScript. SameSite=Lax, который в современных браузерах используется по умолчанию, если не указан, блокирует большинство межсайтовых POST; используйте Strict для особо чувствительных cookie, а None; Secure — только когда межсайтовое использование действительно нужно. Префикс __Host- требует Secure, Path=/ и отсутствия атрибута Domain, поэтому скомпрометированный поддомен не сможет перезаписать cookie. CORS часто понимают неправильно: он ослабляет same-origin policy, а не защищает ваш API. Никогда не отражайте произвольные значения Origin вместе с Access-Control-Allow-Credentials: true; держите явный allow-list. Для более сильной изоляции Cross-Origin-Opener-Policy: same-origin отделяет ваше окно от cross-origin попапов, а Cross-Origin-Resource-Policy ограничивает, какие сайты могут встраивать ваши ресурсы.

http
Set-Cookie: __Host-session=9f1c...; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=3600
 
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Vary: Origin
 
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-site

Реальные ситуации

01

API-ключ попал в публичный репозиторий

Проблема

Разработчик закоммитил секретный ключ платёжного провайдера в публичный репозиторий. Через час его удалили следующим коммитом.

Как решить

Считайте ключ скомпрометированным: боты сканируют публичные репозитории в течение минут. Немедленно отзовите или ротируйте ключ в панели провайдера, задеплойте новый ключ через переменные окружения или secrets manager и проверьте логи провайдера на активность с неизвестных IP за время утечки. Затем почистите историю, если репозиторий должен остаться публичным, понимая, что это не отменяет утечку. Добавьте secret scanning с push protection, pre-commit hook и более узкие ограниченные ключи для каждого сервиса, чтобы у будущей утечки был меньший радиус поражения.

02

IDOR, найденный на пентесте

Проблема

Пентест показывает, что изменение ID счёта в /api/invoices/{id}/pdf позволяет скачивать счета других клиентов. Эндпоинт добавили наспех для мобильного приложения.

Как решить

Сначала исправьте эндпоинт: загружайте счёт запросом, ограниченным аккаунтом текущего пользователя, возвращайте 404, если не найдено, и задеплойте. Затем поищите в кодовой базе тот же паттерн — любой обработчик, загружающий по ID без ограничения области, — и проведите их через политику или scoped repository. Добавьте автоматический набор тестов авторизации, который вызывает каждый эндпоинт от имени второго пользователя и ожидает 404 или 403. Просмотрите access-логи за период существования эндпоинта, чтобы понять, эксплуатировался ли он, и если да, уведомите затронутых клиентов.

03

Внедрение CSP на существующем сайте

Проблема

На маркетинговом сайте с аналитикой, чат-виджетом и инлайн-скриптами нет CSP. Включить политику за один шаг — значит сломать функциональность.

Как решить

Начните с Content-Security-Policy-Report-Only и эндпоинта для отчётов, используя политику на nonce с 'strict-dynamic'. Добавляйте nonce каждого ответа к легитимным инлайн- и внешним скриптам через фреймворк (это умеют Next.js middleware или серверные шаблоны). Неделю собирайте отчёты, исправьте или удалите нарушающие скрипты и перенесите инлайн-обработчики событий в файлы скриптов. Затем включите применение политики, оставьте отчёты включёнными и добавьте проверку в CI или правило code review для любого нового стороннего скрипта.

Шпаргалка

Хэширование паролей
Argon2id, m=19 MiB, t=2, p=1 (минимум по OWASP)
Сессионная cookie
__Host-session=...; Path=/; Secure; HttpOnly; SameSite=Lax
Ядро строгой CSP
script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none'
Проверить CSP, ничего не сломав
Content-Security-Policy-Report-Only: ...
Заблокировать DOM XSS sink
require-trusted-types-for 'script'
Аудит зависимостей Node
npm audit --omit=dev
Аудит зависимостей PHP
composer audit
Найти секреты в истории Git
gitleaks detect --source .
Требовать IMDSv2 в AWS
aws ec2 modify-instance-metadata-options --instance-id i-0abc --http-tokens required
Быстро проверить заголовки
curl -sI https://example.com

В моих реальных проектах

  • В POS SaaS аутентификация использует JWT с RS256, перепроверяемые на каждый запрос с denylist'ом, 2FA для персонала и операторов и API-ключи с ограниченными правами, режимами live/test, rate limit'ами и ротацией.
  • Загружаемые там медиа проверяются по содержимому, защищены от decompression bomb'ов и отдаются через подписанные приватные ссылки, а исходящие вебхуки подписываются HMAC.
  • Мой базовый набор для серверов: вход по SSH только по ключам, firewall, разрешающий лишь порты 22, 80 и 443, базы никогда не открыты публично, fail2ban и unattended upgrades, HTTPS везде.
  • На платформе зоотоваров поиск ограничен rate limit'ом, а вход в админку использует OTP; в общих пакетах сырые данные карт не попадают в сохраняемое хранилище корзины.

Вопросы и ответы

Q1Какая серьёзная уязвимость встречается в веб-приложениях чаще всего?

Broken access control — первое место в OWASP Top 10. Обычно API проверяет, что пользователь аутентифицирован, но не что ему разрешён доступ к конкретному объекту, так что замена ID в URL возвращает чужой заказ или счёт. Это распространено, потому что аутентификацию за вас делают фреймворки, а ваших бизнес-правил они знать не могут. Я предотвращаю это централизованными политиками авторизации, вызываемыми на каждый запрос, ограничением запросов по пользователю или tenant'у, запретом по умолчанию и возвратом 404 для недоступных объектов, плюс автоматическими тестами, которые со второго аккаунта пытаются получить запрещённый доступ.

Q2Как предотвратить SQL-инъекции?

Никогда не собирать SQL конкатенацией строк с пользовательским вводом. Используйте параметризованные запросы или prepared statements, где текст SQL и значения передаются отдельно, так что ввод не может изменить структуру запроса. ORM и query builder'ы делают это по умолчанию, но их хелперы для сырых запросов и динамические идентификаторы вроде колонок сортировки — именно там баги возвращаются; им нужны allow-list'ы. Для эшелонированной защиты пользователь базы должен иметь только те привилегии, которые нужны приложению, а ошибки не должны раскрывать детали SQL. Код-ревью и статический анализ ловят большую часть оставшихся случаев.

Q3Что такое Content Security Policy и как её внедрять?

CSP — HTTP-заголовок, который говорит браузеру, из каких источников разрешены скрипты, стили, изображения, фреймы и соединения. Если атакующий внедрит тег script, браузер откажется его выполнять, если он не соответствует политике, — это делает CSP сильным вторым слоем защиты от XSS. Я внедряю её постепенно: начинаю с Content-Security-Policy-Report-Only и сборщика отчётов, устраняю нарушения от легитимных источников, затем включаю принудительно. Для inline-скриптов предпочитаю nonce или хэши вместо 'unsafe-inline', добавляю object-src 'none', base-uri 'self' и frame-ancestors против clickjacking и пересматриваю политику при каждом изменении сторонних скриптов.

Q4XSS и CSRF: в чём разница?

XSS (cross-site scripting) означает, что атакующему удаётся запустить свой скрипт внутри вашего сайта, например через неэкранированный комментарий. Этот скрипт выполняется с правами пользователя на вашем origin, так что может читать страницу и отправлять запросы. CSRF (cross-site request forgery) означает, что другой сайт заставляет браузер пользователя отправить запрос на ваш сайт, пользуясь его cookie, не запуская код на вашем origin. XSS предотвращают экранированием вывода, санитизацией и CSP. CSRF — cookie с SameSite, anti-CSRF-токенами и проверкой Origin. Учтите, что XSS обходит защиту от CSRF, потому что скрипт может прочитать токены.

Q5Как вы управляете секретами в проекте?

Секреты никогда не попадают в репозиторий, клиентский бандл или логи. Они живут в переменных окружения, передаваемых при деплое, или, что лучше, в менеджере секретов с контролем доступа и журналом аудита. У каждого окружения свои секреты, у каждого секрета — минимально необходимые права, а ротация — рутинная задокументированная операция. Сканирование секретов работает в pre-commit хуках и в CI. Если секрет утёк, я сначала ротирую его, а потом разбираюсь, потому что удаление из истории Git не поможет, если его уже запушили: кто угодно мог его скопировать.

Q6Что бы вы проверили при быстром ревью безопасности веб-приложения?

Начинаю с контроля доступа: может ли пользователь A добраться до ресурсов пользователя B, поменяв ID, и защищены ли админские эндпоинты на сервере? Затем аутентификация: хэширование паролей, rate limiting на вход и OTP, работа с сессиями и токенами. Затем обработка ввода: параметризованные запросы, экранирование вывода, валидация загрузки файлов и любая загрузка URL на стороне сервера. Дальше конфигурация: режим отладки, страницы ошибок, открытые файлы, заголовки безопасности, CORS и флаги cookie. Потом секреты в репозитории и результаты аудита зависимостей. И наконец, логирование: записываются ли неудачные входы и отказы в доступе и есть ли на них алерты? Это быстро покрывает большую часть Top 10.

Вопросы уровня senior

S1JWT или серверные сессии: что бы вы выбрали и почему?

Для собственного веб-приложения серверные сессии с непрозрачным ID в cookie с префиксом __Host- обычно более безопасный выбор по умолчанию: мгновенный отзыв, маленькие cookie и никаких подводных камней с парсингом токенов. JWT полезны, когда многим сервисам нужно проверять личность без обращения к центральному хранилищу, или для доступа к API третьих сторон. Их цена: для отзыва нужен короткий срок жизни плюс denylist или перепроверка на каждый запрос, работа с алгоритмами и ключами должна быть строгой, а хранение в localStorage открывает их для XSS. Распространённый гибрид — короткоживущие access-токены, порядка минут, с ротируемыми refresh-токенами в HttpOnly cookie и обнаружением повторного использования. Что бы вы ни выбрали, подписывайте асимметричными ключами, когда проверяют несколько сервисов, ротируйте ключи с key ID и логируйте события аутентификации для обнаружения атак.

S2Как встроить безопасность в пайплайн доставки, не замедляя команды?

Автоматизируйте дешёвые и точные проверки, а человеческое внимание оставьте для дизайна. В пайплайне: secret scanning с push protection, аудит зависимостей, который падает только на проблемах высокой критичности с доступным исправлением, SAST, настроенный на небольшой проверенный набор правил, lockfile и закреплённые версии CI actions, а также сканирование образов контейнеров. Блокируйте merge на значимых находках, остальное отправляйте в бэклог с владельцами. Перед написанием кода проводите короткую сессию threat modelling для фич, затрагивающих аутентификацию, платежи, загрузки или границы тенантов. Давайте безопасные настройки по умолчанию в общих библиотеках — scoped repository, HTTP-клиент с защитой от SSRF и middleware для заголовков, — чтобы безопасный путь был лёгким. Компромисс — усилия на настройку и тюнинг: ненастроенные инструменты создают шум, который разработчики привыкают игнорировать.

S3Как бы вы отреагировали на критическую уязвимость, раскрытую в используемой вами зависимости?

Относитесь к этому как к инциденту, где время идёт. Сначала определите подверженность: есть ли уязвимый пакет в продакшен-сборках, в затронутой версии, и достижим ли уязвимый путь кода с входными данными под контролем злоумышленника? Software bill of materials или поиск по lockfile отвечают на первые два вопроса за минуты. Если вы подвержены, смягчайте самым быстрым способом: обновитесь или примените патч либо временную меру — правило WAF, отключение функции или блокировку шаблона ввода. Деплойте через обычный пайплайн, но в ускоренном режиме, и проверьте исправление. Проверьте логи на попытки эксплуатации с момента раскрытия и ротируйте секреты, если было возможно выполнение кода. После этого разберите, почему обнаружение заняло столько времени и поймали бы это раньше инструменты автоматического обновления.

Глоссарий

IDOR
Insecure direct object reference: доступ к чужому объекту через изменение идентификатора.
SSRF
Server-side request forgery: принуждение сервера запрашивать внутренние или непредусмотренные URL.
CSRF
Поддельный межсайтовый запрос, который использует cookie жертвы, чтобы изменить состояние.
XSS
Cross-site scripting: скрипт под контролем злоумышленника, выполняющийся на страницах вашего сайта.
CSP nonce
Случайное значение для каждого ответа, помечающее, какие скрипты браузеру разрешено выполнять.
Trusted Types
Функция браузера, блокирующая сырые строки в опасных DOM sink, если они не прошли через политику.
Argon2id
Memory-hard алгоритм хэширования паролей, рекомендованный OWASP для их хранения.
DNS rebinding
Приём, при котором hostname во время проверки резолвится в безопасный IP, а позже — во внутренний.
Атака на цепочку поставок
Компрометация ПО через его зависимости, инструменты сборки или пайплайн доставки.

Есть идея продукта?Давайте создадим его.

Расскажите о своей идее, продукте или команде. Обычно отвечаю в течение одного рабочего дня.