Чек-лист безопасности API
Действительный JWT подтверждает, кто является вызывающей стороной. Но он не подтверждает, что она может прочитать заказ 12345. Уязвимость, которую я обычно ставлю в приоритет, возникает уже после аутентификации: владение объектом, разрешения на уровне полей, ограничения ресурсов или бизнес-правила никогда не применялись.
Но этот чек-лист лучших практик безопасности API предназначен для производственных проверок в 2026 году. Он прослеживает один запрос от идентификации через разрешение, использование ресурсов, обработку входных данных, транспорт, обнаружение, секреты и проверку. Скопируйте проверки в инженерные задачи или тесты pass/fail.
При этом этот чек-лист лучше всего охватывает авторизацию и обработку запросов. Он не заменяет моделирование угроз для регулируемой платёжной системы или проверку реализации вашего провайдера идентификации.
В этой статье
- Издания OWASP API Security Top 10 за 2026 год не существует
- Аутентификация зависит от клиента и границы доверия
- Валидации JWT по-прежнему нужна стратегия отзыва
- Действительный токен не авторизует доступ к объекту
- Разрешения на уровне полей блокируют mass assignment
- Сделайте злоупотребляющие запросы дорогими для отправки и дешёвыми для отклонения
- Проверяйте данные на границе и отклоняйте небезопасный ввод
- Внутренним вызовам тоже нужен TLS
- Логи должны объяснять отказ
- Секреты — это учётные данные, поэтому при возможной утечке их нужно ротировать
- Запускайте чек-лист как тесты, а не как документ с политиками
Издания OWASP API Security Top 10 за 2026 год не существует
А OWASP API Security Project указывает API Security Top 10:2023, выпущенный 5 июня 2023 года, как текущее стабильное издание. Называть его «списком OWASP 2026» было бы неточно: 2026 — это дата проверки, а не номер издания.
Таким образом, таксономия охватывает API1 Broken Object Level Authorization, API3 Broken Object Property Level Authorization, API4 Unrestricted Resource Consumption, API5 Broken Function Level Authorization, API6 Sensitive Business Flows, API7 SSRF, API9 Improper Inventory Management и API10 Unsafe Consumption of APIs. OWASP также охватывает нарушения аутентификации и неправильную конфигурацию безопасности.
OWASP предоставляет таксономию рисков. Моё практическое применение проще: сопоставьте каждому маршруту владельца, предикат авторизации и тест. Руководство Blackhawk по penetration testing REST API охватывает практическое тестирование, которое следует за проверкой дизайна.
[IMAGE PLACEHOLDER: визуальное представление OWASP API Security Top 10 (2023) с чёткой пометкой «текущее стабильное издание по состоянию на 22 августа 2026 года»; источник/ссылка на OWASP API Security Top 10]
Аутентификация зависит от клиента и границы доверия
Начните с разделения функций OAuth, JWT и API keys. OAuth 2.0 — это authorization framework, JWT — формат токена, а API key — учётные данные. API key обычно идентифицирует приложение или интеграцию; сам по себе он не содержит разрешений на уровне объектов.
| Клиент или интеграция | Подходящая отправная точка | Проверки, поддающиеся тестированию |
|---|---|---|
| Пользователь браузера или мобильного приложения | Authorization Code with PKCE | Проверьте redirect URI, обмен authorization code, PKCE verifier, audience токена и scopes |
| Машинный клиент в пределах одной границы доверия | OAuth 2.0 Client Credentials | Предоставьте каждому клиенту узкие scopes; проверяйте аутентификацию клиента и отзывайте учётные данные при offboarding |
| Межорганизационная или регулируемая интеграция | mTLS или OAuth with mTLS | Проверьте сертификат клиента, цепочку сертификатов, срок действия и привязку сертификата или токена |
| Планируемая задача или webhook с низкой чувствительностью | API key | Ограничьте scope ключа, ротируйте и отзывайте его, а также применяйте ограничения для endpoint и tenant |
| Public client, которому нужны sender-constrained tokens | DPoP, если ваш провайдер и библиотеки его поддерживают | Проверьте подпись proof, HTTP-метод, URL запроса, nonce или поведение replay и привязку токена |
И используйте поддерживаемую OAuth-библиотеку или identity service. Сравнение Skycloak полезно для выбора между типами клиентов, но окончательное решение по безопасности всё равно принимает ваш API.
OAuth выдаёт клиенту access token; ваш API всё ещё решает, может ли этот токен выполнить эту операцию над этим объектом. Эти решения должен принимать ваш сервер.
Для каждого bearer- или JWT access token проверяйте его подпись по доверенному набору ключей. Проверяйте разрешённый algorithm, issuer, audience, expiry и обязательные claims. Никогда не помещайте client secrets в browser bundles или мобильные приложения. В руководстве по безопасности Node.js и руководстве по безопасности Django рассматривается обработка токенов и middleware для конкретных frameworks.
Валидации JWT по-прежнему нужна стратегия отзыва
Для GET /profile или обычной операции чтения локальная валидация часто практична. Но восстановление аккаунта и авторизация платежа могут требовать вызова introspection, чтобы проверить текущее состояние токена.
| Метод | Преимущество | Стоимость |
|---|---|---|
| Локальная валидация с помощью JWKS | Быстрая, способна работать offline и не зависит от вызова authorization server во время запроса | Отозванный токен может оставаться пригодным к использованию до истечения срока действия |
| Introspection | Отражает текущее состояние токена и быстро обнаруживает отзыв | Добавляет задержку и зависимость от authorization server |
Используйте локальную валидацию, когда окно expiry соответствует вашей модели риска. Рассмотрите introspection для платежей и восстановления аккаунта. Используйте её также при изменении разрешений или в других сценариях, где отзыв критически важен. Уменьшение срока действия снижает воздействие; оно никогда не заменяет авторизацию объекта или контроль отзыва.
Access token на 15 минут и refresh token на семь дней — конкретные отправные точки из вторичных рекомендаций практиков; OWASP их не требует. Я не могу выбрать ваше окно expiry, не зная вашего набора клиентов, потребностей в отзыве и допустимого уровня последствий инцидента.
Зафиксируйте допустимые algorithms, ротируйте signing keys и отклоняйте alg:none, неутверждённые algorithms, неправильный issuer, неправильную audience и просроченные токены. Тестируйте эти отказы напрямую.
Действительный токен не авторизует доступ к объекту
Рассмотрим multi-tenant order API. Этот handler аутентифицирует вызывающую сторону, а затем доверяет идентификатору, предоставленному вызывающей стороной:
app.get("/api/orders/:id", auth, async (req, res) => {
const order = await db.orders.findById(req.params.id);
return res.json(order);
});
Более безопасный lookup включает предикат авторизации непосредственно в операцию доступа к данным:
app.get("/api/orders/:id", auth, async (req, res) => {
const order = await db.orders.findOne({
id: req.params.id,
tenantId: req.user.tenantId,
ownerId: req.user.id
});
if (!order) {
return res.sendStatus(404);
}
return res.json(order);
});
Этот пример предполагает, что просматривать заказ может только владелец. Если заказ виден нескольким пользователям в tenant, замените ownerId фактическим предикатом политики: членство в tenant, связь с аккаунтом, роль или другое явно заданное правило.
OWASP API1 формулирует требование прямо: «Проверки авторизации на уровне объектов следует учитывать в каждой функции, которая обращается к источнику данных, используя ID от пользователя». Применяйте эту проверку к чтению, обновлению, удалению, вложенным ресурсам, экспортам и фоновым действиям.
Ответ 404 — распространённый выбор для объектов за пределами видимой области вызывающей стороны, поскольку он не раскрывает существование объекта. Я бы моделировал доступ сотрудников как отдельную явную политику, а не молча убирал условие владения для всех.
BOLA, или Broken Object Level Authorization, — термин OWASP. Команды по-прежнему часто называют уязвимости, связанные с заменой идентификаторов, IDOR. Для предотвращения BOLA и IDOR тестируйте с двумя обычными пользователями, а не с администратором:
- Заменяйте идентификаторы. Изменяйте числовые ID, UUID, вложенные идентификаторы и идентификаторы tenant.
- Охватите каждый метод. Тестируйте пути
GET,PATCH,DELETEи экспорта. - Тестируйте границу. Используйте пользователей из одного tenant и из разных tenant.
- Проверяйте выводы. Сравнивайте коды состояния, размеры ответов и время выполнения для недоступных объектов.
Пользователь с низкими привилегиями должен безуспешно завершать каждую попытку прочитать, изменить, удалить, экспортировать или определить наличие заказа другого tenant. Используйте руководство по Node.js для деталей реализации в Express; проводите всю процедуру в рамках процесса security testing.
Разрешения на уровне полей блокируют mass assignment
Передача req.body через spread позволяет вызывающей стороне попытаться изменить status, ownerId или paymentState:
await db.orders.update(req.params.id, {
...req.body
});
Доступное для записи поле role или isVerified создаёт возможность повышения привилегий. Возврат внутренних полей создаёт чрезмерное раскрытие данных. OWASP API3:2023 объединяет обе прежние проблемы под названием Broken Object Property Level Authorization.
Сначала проверьте body, затем создайте allow-list:
const body = updateOrderSchema.parse(req.body);
const updates = {
shippingAddress: body.shippingAddress,
deliveryInstructions: body.deliveryInstructions
};
await db.orders.updateOwned(req.params.id, req.user.id, updates);
В этом примере шаг schema показан для иллюстрации разрешений; для него всё ещё нужны правила типов полей, длины и вложенных значений.
Отделяйте изменения workflow, контролируемые сервером, от обычных обновлений. Клиент может изменить адрес доставки, тогда как только авторизованный workflow может изменить состояние платежа. Возвращайте response DTO, а не объекты базы данных, чтобы audit fields, metadata tenant, платёжные данные и административные флаги оставались внутренними.
Проверки объектов и свойств оставляют третью границу: может ли эта вызывающая сторона вообще вызвать функцию. API5 охватывает это решение на уровне функции, особенно для административных маршрутов. Тестируйте попытки вызвать admin endpoints с токенами обычных пользователей.
Сделайте злоупотребляющие запросы дорогими для отправки и дешёвыми для отклонения
Rate limiting — не декоративная настройка gateway. Для login, password reset, search, export и pagination нужны разные ограничения. Они также нужны дорогим бизнес-операциям. Квоты tenant не менее важны, чем ограничения по IP.
Это отправная политика, готовая для добавления в ticket:
- Login: пять попыток за 15 минут на IP с контролем на основе identity там, где это уместно.
- Password reset: более строгие ограничения, чем для обычных чтений, с alert об abuse.
- Search и export: отдельные ограничения endpoint, ограниченные наборы результатов и квоты на tenant.
- Pagination: устанавливайте максимальный
limit; отклоняйте неограниченные list requests. - Business flows: ограничивайте действия, похожие на checkout, по identity, tenant и business state; одних ограничений по IP недостаточно.
- Failure behavior: возвращайте
429 Too Many RequestsиRetry-After; применяйте консервативный fallback, если состояние limiter недоступно.
Пример «пять попыток за 15 минут на IP» взят из практических рекомендаций Quantlab. Это не default OWASP. В общих офисных сетях и мобильных операторах многие пользователи могут находиться за одним адресом, поэтому перед внедрением измерьте количество false positives.
Для order API тестируйте чрезмерно большие значения GET /api/orders?limit=..., повторяющиеся exports, дорогие searches и повторяющиеся запросы, похожие на checkout, пока обычные чтения остаются ниже своего лимита. Ограничения должны ограничивать bandwidth, CPU, memory, storage и business capacity.
Пример ответа; используйте формат, поддерживаемый вашим gateway и клиентами:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
RateLimit-Limit: 60
RateLimit-Remaining: 0
Проверяйте данные на границе и отклоняйте небезопасный ввод
Проверяйте значения path, query, header и body до того, как business logic или persistence начнут их обрабатывать. Строгие schemas, такие как Zod, JSON Schema и Pydantic, должны обеспечивать проверку типов и обязательных полей. Они также должны проверять длины, диапазоны, форматы, перечисляемые значения и допустимую вложенность.
Используйте этот чек-лист границы:
- Schema: отклоняйте значения за пределами контракта; нормализуйте только там, где контракт определяет нормализацию.
- Business rules: требуйте положительные, ограниченные количества; shipped order не должен возвращаться в
pending. - Content: проверяйте
Content-Type, размер payload и поддерживаемые encodings. - Database: используйте prepared statements и parameterized queries. Руководство Blackhawk по SQL injection охватывает построение queries и тестирование, специфичное для injection.
- URLs: если API получает удалённый ресурс, разрешайте destinations по allow-list. Блокируйте внутренние диапазоны и диапазоны cloud metadata. Проверяйте каждую destination, к которой HTTP client действительно обратится.
- Third-party data: разбирайте ответы провайдера по schema, устанавливайте ограничения размера и не допускайте попадания их полей в privileged update paths.
OWASP API7 охватывает SSRF, а API10 — небезопасное использование внешних APIs. Строка, похожая на URL, всё равно является пользовательским вводом.
Внутренним вызовам тоже нужен TLS
Принудительно используйте HTTPS и TLS для public endpoints и вызовов внутренних сервисов. К внутреннему маршруту всё ещё можно получить доступ после ошибки маршрутизации, компрометации workload или неправильной настройки proxy. Требуйте аутентифицированную service identity всякий раз, когда downstream service принимает решения об авторизации.
Проверьте три вещи:
- Plaintext HTTP отклоняется или перенаправляется в соответствии с политикой вашего deployment.
- Outbound clients проверяют сертификаты и отклоняют недействительные, просроченные или неожиданные identities.
- Тесты webhook отклоняют отсутствующие или недействительные signatures, устаревшие timestamps и повторно использованные event IDs, когда провайдер предоставляет replay controls.
Используйте актуальную поддерживаемую платформой конфигурацию безопасного TLS вместо копирования статического списка cipher в чек-лист. Не помещайте bearer tokens в URLs, analytics data и logs.
Логи должны объяснять отказ
Большинство проверок API уделяет слишком много внимания валидации токенов, потому что её легко продемонстрировать. С логированием происходит обратное: создаётся расплывчатая задача «добавить observability», но нет доказательств, что расследователь сможет восстановить картину атаки.
При отказе в авторизации записывайте наименее чувствительный идентификатор, который всё ещё поддерживает расследование, вместе с контролями хранения и доступа. Эскиз schema должен содержать:
{
"event": "authorization_denied",
"requestId": "<request identifier>",
"actor": "<user or service identifier>",
"tenant": "<tenant identifier>",
"requestPath": "/api/orders/:id",
"endpoint": "GET /api/orders/:id",
"object": "<order reference>",
"action": "read",
"policy": "order_owner_or_tenant_member",
"reason": "object_outside_actor_scope",
"outcome": "denied",
"timestamp": "<UTC timestamp>",
"clientContext": "<redacted network or client context>"
}
Логируйте authentication failures и authorization denials. Логируйте действия высокой ценности, exports, события rate limit и доступ к deprecated или debug endpoints. Никогда не логируйте passwords, access tokens или sensitive payloads.
Настройте alert на повторяющиеся ответы 401 и 403, patterns перебора identifiers, необычные exports и внезапные всплески rate limit. Поддерживайте inventory endpoints и versions. После изменения аутентификации или доступа к данным я бы настоял на новом запуске pentest, а не полагался на старый отчёт.
Секреты — это учётные данные, поэтому при возможной утечке их нужно ротировать
Храните API keys, database passwords, signing keys и service credentials в управляемом secrets store. Ограничивайте каждый secret минимально необходимыми permissions и environment. Никогда не встраивайте secrets в browser bundles или мобильные приложения: клиенты могут их извлечь.
Если credential мог утечь:
- Определите каждую систему, которая его использует.
- Немедленно отзовите или отключите его.
- Выпустите замену с более узким scope.
- Удалите его из source, history, build artifacts, logs и error responses.
- Проверьте access records на предмет злоупотребления.
- Ротируйте связанные credentials, если они подверглись той же утечке.
Утёкший key — это инцидент, даже если у вас нет доказательств его использования. По возможности используйте short-lived tokens, если интеграция их поддерживает, и ротируйте их как по расписанию, так и при подозрении.
Запускайте чек-лист как тесты, а не как документ с политиками
Скопируйте эти строки в release ticket. Каждое условие pass называет evidence, которое может проверить reviewer.
| Проверка | Условие pass | Evidence |
|---|---|---|
| Inventory endpoints | Известны каждый host, route, version, debug endpoint и deprecated version | Versioned route inventory с owner и датой вывода из эксплуатации |
| Authentication | Механизм соответствует клиенту; проверяются issuer, audience, expiry, signature, algorithm и claims | Middleware tests с демонстрацией принятых и отклонённых токенов |
| Object authorization | Изменения identifiers между пользователями и tenant завершаются отказом для чтений, обновлений, удалений, вложенных ресурсов и exports | Test matrix с пользователями низких привилегий и assertions ответов |
| Property authorization | Доступные для записи поля находятся в allow-list; sensitive fields нельзя назначить через mass assignment | Schema, DTO и negative tests изменения полей |
| Function authorization | Административные и обычные функции применяют отдельные policies | Role или policy tests для каждого privileged route |
| Resource controls | Pagination, payloads, queries, exports, business flows и использование tenant ограничены | 429 tests, quota configuration и tests максимальных значений |
| Validation | Проверяются schemas, content types, URLs, SQL inputs и ответы third-party | Результаты boundary tests и review prepared queries |
| Transport | TLS применяется на каждом hop, а webhook signatures проверяются | Plaintext, certificate, signature, timestamp и replay tests |
| Detection | Security events содержат actor, tenant, route, action, outcome, reason и time без secrets | Redacted event samples и alert rules |
| Secrets | Credentials имеют scope, безопасно хранятся, ротируются и могут быть отозваны | Secrets inventory, rotation record и repository scan |
| Retesting | Изменения authentication и data access запускают security testing до release | Связанный test run или утверждённое исключение |
Для order API создайте Alice и Bob в tenant A. Поместите Carol в tenant B. Протестируйте каждую комбинацию order IDs и tenant context. Попробуйте изменить поля и использовать чрезмерно большую pagination. Повторяйте exports и пытайтесь злоупотреблять business flows. OWASP API Security Project также указывает crAPI, намеренно уязвимый API project, для безопасной практики.
Нет теста отказа для cross-tenant — нет release.