Перейти к содержимому
>_ITDITDПлатформа веб-безопасности

Руководства по безопасности

Добавили вход и решили, что защищено? — аутентификация и авторизация

Аутентификация (кто) и авторизация (что можно делать) — разное. Вход без привязки данных к владельцу даёт «вошёл = видит все данные». Почему так и как защититься.

Опубликовано 2026-06-30 Обновлено 2026-07-03 5 мин чтения

«Я добавил вход, значит теперь защищено» — это опасное допущение. Вход (аутентификация) и права (авторизация) — разные вещи, и путаница между ними приводит к инциденту, когда все, кто вошёл, видят все данные, включая чужие. Никаких шагов атаки — только как это происходит и как защититься.

Аутентификация и авторизация — разные вещи

Их легко спутать, но роли у них совершенно разные.

Только аутентификация (частая ошибка)

  • считать «может войти = безопасно»
  • обрабатывать чтение данных после входа одинаково для всех
  • итог: все, кто вошёл, добираются до всех данных

Аутентификация + авторизация (как должно быть)

  • аутентификация подтверждает «кто»
  • авторизация ограничивает «только теми данными, к которым можно обращаться»
  • чтение данных всегда привязано к владельцу

Аутентификация — это «проверка документов на входе»; авторизация — «контроль того, в какие комнаты можно войти». Вход гарантирует только первое. «Кто к каким данным может обращаться» нужно писать отдельно.

authn
Проверка «кто» на входе (вход в систему)
authz
Контроль «кому можно войти» по каждой комнате (привязка к владельцу)
no authz
Вошёл = все комнаты = каждый вошедший видит все данные
Аутентификация лишь проверяет личность на входе. Без ключа от каждой комнаты (авторизации) любой, кто вошёл, может зайти в любую комнату.

Как «видит все данные» возникает в реальных приложениях

На практике одна и та же дыра снова и снова находится в независимых самописных системах. Личное приложение для задач/заметок или небольшая система управления товарами/заказами (с интеграциями внешних API) — причина была одна и та же: наложение двух изъянов.

1

① Регистрация открыта (и на двух маршрутах)

Auth-scaffold (вроде Laravel Breeze/Jetstream) часто по умолчанию поставляются с публичной страницей регистрации. А когда маршрут регистрации дублируется в UI-библиотеке и в auth-пакете, закрытие одного всё равно оставляет /register. Посторонний, знающий URL, может зарегистрироваться.

2

② Аутентификация есть, а авторизации нет (нет привязки к владельцу)

В таблице данных нет столбца владельца (user_id), либо запросы списка/чтения/обновления/удаления не сужены до текущего пользователя. Тогда «вошёл = доступ ко всем данным». Если приложение автоматически входит сразу после регистрации, посторонний попадает на чужой список данных в момент регистрации.

3

Итог: инцидент authn ≠ authz

Вход (аутентификация) есть, а ключей от комнат (авторизации) нет. Поскольку посторонний ведёт себя как «нормально вошедший пользователь», от несанкционированного доступа почти не остаётся следов.

Радиус поражения тем больше, чем больше задействовано бизнес-данных (могут пострадать записи клиентов, заказы, ключи интеграционных API). А другая система, построенная так же, скорее всего, имеет ту же дыру.

Как защититься

1

Всегда привязывайте данные к владельцу

Ограничивайте каждое чтение и запись «собственными строками вошедшего пользователя». Обеспечивайте условие владельца во всех действиях чтения/обновления/удаления через глобальный scope в ORM или политику авторизации (policy/gate). Если в таблице нет столбца владельца, сначала перепроектируйте её.

2

Закрывайте ненужную регистрацию — и подозревайте дублирование маршрутов

Отключайте регистрацию в личных/внутренних приложениях. Реально измерьте по HTTP, что /register и подобные возвращают 404, и проверьте оба маршрута регистрации — и в UI-библиотеке, и в auth-пакете.

3

Эшелонированная оборона на административных интерфейсах

Для внутреннего/административного использования не полагайтесь только на аутентификацию — добавляйте IP-ограничения, Basic-аутентификацию и подобное. Если одна стена падает, следующая останавливает.

4

Аудит и логи доступа *до* инцидента

Без «кто, когда, с какого IP, что сделал» после инцидента нельзя восстановить, «что было увидено». Как минимум ведите аудит успешных/неуспешных входов и храните с ротацией веб-логи доступа.

5

Отслеживайте новые регистрации и аномалии

Ключевой урок здесь — «долгое время оставалось незамеченным». Добавьте способы замечать быстро — уведомления о регистрации нового пользователя, периодическую инвентаризацию пользователей/данных. Без детектирования дыра тихо остаётся открытой.

Взгляд этого сайта: библиотека гарантирует только «кто»

Auth-библиотека берёт на себя «кто» — и не более. «Что этому человеку можно делать» не существует, пока вы, проектировщик, это не напишете. И — структурный изъян, найденный в одной системе, вероятно, есть и в других системах, построенных так же. Не исправляйте один и не останавливайтесь; проверяйте все однотипные сборки. Когда нельзя определить, было ли что-то прочитано, правильная позиция — считать, что прочитано, и отозвать/сменить любые раскрытые секреты.

Читать далее

Источники

FAQ

QЧем аутентификация и авторизация отличаются?
A

Аутентификация проверяет, кто вы (вход). Авторизация решает, что вам можно делать (права). По аналогии: аутентификация — это проверка документов на входе в здание; авторизация определяет, в какие комнаты вам можно войти. Добавляя вход, вы реализуете только аутентификацию — авторизацию (кто к каким данным может обращаться) нужно писать отдельно. Смешаете эти два понятия — и получите «все, кто вошёл, видят все данные».

QВход есть — почему же все видят все данные?
A

Потому что запрос к данным не сужен до «только строки вошедшего пользователя». Забудьте условие владельца (user_id) в любом из действий — список/чтение/обновление/удаление — и после входа возвращаются все строки, включая чужие. Это дыра в проектировании, не зависящая от наличия аутентификации, и это классический Broken Access Control, который OWASP ставит на первое место.

QДля личного инструмента или внутреннего приложения ведь можно оставить регистрацию открытой?
A

Это опасно. Многие auth-scaffold по умолчанию поставляются с публичной регистрацией (например, /register). Если посторонний знает URL, он может зарегистрироваться, и без авторизации сразу попадает к данным внутри. Маршруты регистрации иногда дублируются (и в UI-библиотеке, и в auth-пакете), поэтому, закрыв один, вы не закрываете всё. Отключайте регистрацию, которая вам не нужна, и добавляйте эшелонированную защиту вроде IP-ограничений на административные интерфейсы.