Информационная безопасность
Безопасность API
Stripe обрабатывает триллионы долларов в год через публичный API. Twilio отправляет миллиарды SMS. GitHub хранит 300 миллионов репозиториев. Все атакуются постоянно - и все работают. Разница не в сложности протокола. В нескольких базовых практиках: key rotation, rate limiting, input validation, Zero Trust. Каждая из них останавливает 90% атак. Вместе - 99%.
- **T-Mobile 2021:** API без rate limiting позволил перебрать 76 млн записей клиентов по номеру телефона - несколько дней автоматического сканирования
- **Optus 2022:** незащищённый API endpoint без AuthN вернул 11 млн записей австралийцев - один GET-запрос, нулевые технические навыки
- **Peloton 2021:** отсутствие object-level authorization позволяло получать данные любого пользователя без логина - миллионы профилей доступны через Burp Suite
API Keys: аутентификация машинных клиентов
2022 год. Исследователи Trufflesecurity сканируют GitHub и находят 4 500 действующих секретов за 24 часа: AWS keys, Stripe secrets, Twilio tokens. Среднее время до первого несанкционированного использования утёкшего ключа - 23 минуты. API keys - самый распространённый способ машинной аутентификации и самый небрежно управляемый.
**GitHub Secret Scanning** автоматически уведомляет Stripe, AWS, Twilio при нахождении их ключей в публичных репозиториях. Stripe деактивирует ключ за секунды. Но между коммитом и деактивацией - минуты, за которые боты успевают создать IAM пользователей, S3 buckets и запустить майнеры.
**JWT vs API Key:** JWT - stateless, содержит claims, истекает автоматически. API Key - stateful, требует хранения в БД, но мгновенно отзывается. Для machine-to-machine без пользователей: API Key или OAuth Client Credentials flow. Для пользовательских сессий: JWT.
Разработчик случайно закоммитил AWS API key в публичный GitHub репозиторий 10 минут назад. Первое действие?
Rate Limiting: защита от злоупотреблений
Без rate limiting API открыт для credential stuffing (миллионы попыток логина), scraping (весь каталог за час), DDoS (перегрузка БД через тяжёлые запросы). T-Mobile 2021: отсутствие rate limiting на API позволило перебрать 76 миллионов записей за несколько дней - каждый запрос возвращал данные клиента по номеру телефона.
| Алгоритм | Burst | Точность | Память |
|---|---|---|---|
| Fixed Window | Да (boundary burst) | Низкая | O(1) |
| Sliding Window Log | Нет | Высокая | O(requests) |
| Token Bucket | Да (контролируемый) | Высокая | O(users) |
| Leaky Bucket | Нет (queue) | Высокая | O(queue size) |
Rate limiter настроен на 100 req/min по IP-адресу. Почему это ненадёжно для аутентифицированного API?
Input Validation: граница доверия
Каждое поле API-запроса - потенциальный вектор атаки. Тип, длина, формат, диапазон - всё проверяется на сервере. Клиентская валидация - UX-помощь, не защита: curl, Burp Suite игнорируют любую browser-side валидацию.
**GraphQL: отключить Introspection в production.** Через `{ __schema { types { name fields { name } } } }` атакующий получает полную схему всех типов и мутаций. Также: depth limit (защита от deeply nested queries), query complexity limit (N+1 protection), query timeout.
API принимает `amount` для платежа как строку и конвертирует через parseInt(). Передан amount="100abc". Что произойдёт?
API Gateway: централизованная безопасность
Применять rate limiting, authN, logging, TLS-терминацию в каждом микросервисе - дублирование и источник ошибок. **API Gateway** централизует cross-cutting concerns: одна точка входа, единая политика безопасности для всех сервисов за ней.
**Zero Trust между микросервисами:** даже за API Gateway, сервисы должны аутентифицировать друг друга через mTLS или service tokens. Компрометация одного сервиса не должна давать доступ ко всем. Istio / Linkerd автоматизируют mTLS без изменения кода приложения.
API Gateway полностью решает безопасность - сервисы за ним не нужно защищать
API Gateway закрывает внешний периметр, но не защищает от lateral movement внутри. Каждый сервис должен валидировать вход, реализовывать authZ и логировать.
При компрометации одного сервиса атакующий делает прямые запросы к соседним, минуя Gateway. Zero Trust требует аутентификации на каждом hop и валидации на каждом сервисе.
Микросервис A делает внутренний HTTP-запрос к микросервису B (оба за API Gateway). Нужна ли аутентификация между ними?
Ключевые идеи
- **API Keys:** 256 бит энтропии, hash в БД, scoping по действиям, ротация каждые 90 дней, pre-commit hook против утечек в git
- **Rate Limiting:** per-user (не per-IP) для AuthN API, строже для sensitive endpoints (login: 5/15min), Token Bucket для burst-дружелюбного UX
- **Input Validation:** Zod/Joi на сервере, whitelist значений, max lengths, type strictness - клиентская валидация не защита
- **API Gateway:** централизует TLS, authN, WAF, rate limiting. Zero Trust между сервисами - mTLS через Istio или service tokens
Связанные темы
API Security строится поверх базовых принципов аутентификации и защиты от инъекций:
- Аутентификация и авторизация — JWT, OAuth, RBAC - фундамент для API authN/authZ
- SQL Injection — API endpoints - основной вектор доставки SQL payload
- IAM и управление доступом — Расширенное управление API-правами через IAM политики
Вопросы для размышления
- Как хранятся API Keys в текущем проекте? Plain text или hash? Есть ли механизм ротации?
- Rate limiting настроен per-user или per-IP? Какой endpoint наиболее критичен для брутфорса?
- Есть ли в codebase места где request.body используется без валидации схемы?
Связанные уроки
- sec-03 — AuthN/AuthZ - основа безопасности API
- sec-07 — SQLi часто эксплуатируется через API endpoints
- sec-08 — CORS критичен для публичных API
- sec-26 — IAM и управление доступом - следующий уровень API security
- net-64-api-gateway