Практическая ситуация: клиент запрашивает чужой ресурс, существование которого нельзя раскрывать. Какой ответ API выбрать?
Следует вернуть 404 Not Found, если раскрытие факта существования ресурса само по себе создаёт угрозу. Для клиента ответы на запрос несуществующего ресурса и существующего, но недоступного ресурса должны выглядеть одинаково.
403 Forbidden уместен, когда клиенту допустимо сообщить, что ресурс существует, но доступ к нему запрещён.
Разделение кодов 404 и 403 возникло как часть стандартной семантики HTTP: 404 сообщает, что ресурс не найден, а 403 — что сервер понял запрос, но отказывает в доступе.
На практике буквальное различие между этими ответами может раскрывать структуру системы. Поэтому в защищённых API появился распространённый приём: скрывать существование чувствительных ресурсов за единым ответом 404.
Предположим, API возвращает 403 для существующего чужого документа и 404 для отсутствующего. Перебирая идентификаторы, злоумышленник сможет определить, какие документы, аккаунты или заказы существуют.
Это создаёт риск перебора идентификаторов, раскрытия фактов о пользователях и подготовки последующих атак. Даже если содержимое ресурса не выдаётся, само наличие объекта может быть конфиденциальной информацией.
Сначала определяется политика раскрытия существования ресурса. Если клиент не должен отличать «ресурс существует, но доступ запрещён» от «ресурса не существует», API возвращает 404 в обоих случаях.
При этом проверка авторизации не отменяется. Сервер всё равно должен проверить аутентификацию, права доступа, принадлежность ресурса и другие ограничения, но наружу отдаёт унифицированный результат.
Внутреннее расследование не должно зависеть от публичного ответа. Сервер может записать в журнал настоящий результат проверки, идентификатор запроса и причину отказа, не включая чувствительные данные в клиентское сообщение.
Важно выравнивать не только HTTP-код. Тело ответа, заголовки, характерные сообщения об ошибке и по возможности время обработки не должны явно различать два сценария. Полностью одинаковое время гарантировать трудно, но заметные различия стоит уменьшать.
403 выбирают, когда существование объекта не является секретом, а клиенту полезно понимать, что проблема именно в правах. Например, сотруднику можно сообщить о существовании документа, доступного только руководителю.
Этот подход не заменяет корректную авторизацию. Нельзя полагаться только на «непредсказуемые» идентификаторы или на скрытие ошибок: права должны проверяться для каждой операции.
В сервисе хранения медицинских документов пользователь мог запрашивать документ по идентификатору. Вариант с 403 для чужого документа был проще для клиентского интерфейса, но позволял перебирать идентификаторы и подтверждать наличие документов других людей.
Вариант с одинаковым 404 лучше защищал конфиденциальность, но усложнял диагностику для клиента: невозможно понять, ошибся ли он в идентификаторе или не имеет доступа. Команда выбрала 404 для внешнего API, а подробную причину оставила в защищённых журналах и административном интерфейсе.
После изменения клиент перестал получать сигнал о существовании чужих документов. Для поддержки добавили корреляцию запросов с внутренними событиями аудита, поэтому расследование отказов сохранилось без раскрытия данных пользователю.
Нет. Если тело ответа, заголовки или время обработки заметно различаются, ресурс всё ещё можно обнаруживать по побочным признакам. Нужно унифицировать внешний формат отказа, ограничивать частоту запросов и применять подходящие меры аудита.
Нет. Это решение зависит от конфиденциальности самого факта существования. Для публичного или явно принадлежащего клиенту ресурса 403 может быть корректнее и удобнее. Унификация в 404 особенно важна для персональных, финансовых, медицинских и иных чувствительных объектов.
Это определяется политикой жизненного цикла данных. Если факт существования или прежнего существования нельзя раскрывать, внешний ответ также должен быть 404. Если клиент имеет право узнать о состоянии объекта, API может использовать отдельное бизнес-состояние, но не должен случайно раскрывать его неавторизованным пользователям.