Безопасность
OWASP Top 10 (2021): что изменилось и почему это важно
Залогиненный пользователь открывает свой счёт по GET /api/invoices/4815 и от скуки правит URL на 4816. Он загружается — чужой счёт, с именем, адресом и последними четырьмя цифрами карты. Никакого эксплойта, ни SQL, ни payload. Просто число, которому сервер поверил, потому что в запросе была валидная сессионная кука. Это IDOR, хрестоматийное лицо Broken Access Control — и в данных OWASP 2021 он занял вершину списка, найденный в 94% всех протестированных приложений.
Что такое Top 10 на самом деле
OWASP Top 10 — это не чек-лист багов, а основанный на данных рейтинг категорий риска, которые чаще всего встречаются в реальных веб-приложениях. Версия 2021 собрана из контрибьюченных данных по более чем 500 000 приложениям от дюжины организаций: восемь из десяти категорий пришли прямо из этих данных, а две добавлены по опросу сообщества, чтобы захватить риски, которые инструменты слишком молоды, чтобы измерить. Эта последняя деталь важнее, чем кажется: именно поэтому категория может попасть в рейтинг без больших исторических чисел за спиной.
Крупнейшее изменение 2021 года — философское. Список реорганизовали вокруг корневых причин вместо симптомов. «Sensitive Data Exposure» — старый #3 — описывал то, что ты видишь после взлома. Его замена, «Cryptographic Failures», называет то, что реально пошло не так: слабая криптография, отсутствие TLS, захардкоженные ключи. Весь список пересобрали против примерно 400 размеченных CWE (против примерно 30 раньше), так что категория теперь группирует реальный режим отказа, против которого можно проектировать, а не исход, который замечаешь слишком поздно.
Broken Access Control: новый #1
Контроль доступа отвечает на один вопрос: можно ли этому аутентифицированному пользователю сделать именно это действие с именно этим ресурсом? Когда ответ вычислен неверно — или не вычислен вовсе — получаешь Broken Access Control. Он поднялся с #5 в 2017 до #1 в 2021, разметив 34 CWE, с наибольшим числом вхождений в датасете среди всех категорий. Заглавная цифра: 94% протестированных приложений показали ту или иную форму broken access control. Это одновременно самый частый и один из самых серьёзных классов.
В продакшене доминируют две формы отказа:
- IDOR (Insecure Direct Object Reference): сервер использует переданный клиентом id, чтобы достать запись, но никогда не проверяет, что запись принадлежит вызывающему.
GET /api/invoices/4816возвращает чужой счёт, потому что запрос былWHERE id = ?, а неWHERE id = ? AND owner_id = ?. - Отсутствие авторизации на уровне функции: UI прячет кнопку админа, поэтому endpoint никто не охраняет. Не-админ, который шлёт
POST /api/admin/users/{id}/promoteнапрямую, получает повышение, потому что единственной «проверкой» была невидимость ссылки.
Рефлекс сеньора — deny by default: любой доступ к ресурсу начинается с «нет», а авторизация проверяется на стороне сервера на конкретной записи и действии — никогда не выводится из спрятанного UI-элемента, claim в JWT, который клиент мог подделать, или самого факта наличия сессии.
| Ранг 2021 | Категория | Изменение vs 2017 | Что это реально значит |
|---|---|---|---|
| A01 | Broken Access Control | Поднялся с #5 | 94% приложений; IDOR + пропуск authz |
| A02 | Cryptographic Failures | Переименован из Sensitive Data Exposure | Причина, не симптом: слабая крипта, нет TLS |
| A03 | Injection | Опустился с #1 | Теперь включает XSS; параметризуй всё |
| A04 | Insecure Design | НОВАЯ | Threat-model до кода; часть дефектов не патчится |
| A05 | Security Misconfiguration | Поднялся с #6 | Дефолтные креды, болтливые ошибки, открытые бакеты |
| A06 | Vulnerable & Outdated Components | Поднялся с #9 | CVE твоих зависимостей — это твои CVE |
| A10 | SSRF | НОВАЯ (по голосованию) | Сервер запрашивает выбранный атакующим URL |
Новые категории эпохи проектирования
Два добавления 2021 года отмечают взросление области за пределы «вычисти ввод». Insecure Design (A04) — это признание того, что часть уязвимостей зашита ещё до написания первой строки: флоу сброса пароля без rate limit, оформление заказа, доверяющее присланной клиентом цене. Из ошибочного дизайна не выпатчишься; фикс — shift-left: смоделируй угрозы для фичи, пиши abuse cases рядом с user stories и закладывай контроль в архитектуру. Это разница между ошибкой кода и отсутствующим требованием безопасности.
SSRF (A10) выделяется по другой причине: у него почти не было исторических данных — он размечает по сути единственный CWE — и всё же он попал в рейтинг, потому что практики проголосовали за него через опрос сообщества. SSRF — это когда твой сервер можно обманом заставить сделать запрос к URL, который контролирует атакующий: фича «загрузи это изображение», направленная на http://169.254.169.254/, чтобы прочитать креды из метаданных облака. Его присутствие в списке, впереди лучше задокументированных багов, — самый чёткий сигнал, что Top 10 отслеживает, куда движется область, а не только то, где старые сканеры уже побывали.
Почему это работает
Почему Injection — многолетний #1 — падает до #3 в 2021? Не потому, что он стал реже, а потому, что инструменты стали хороши. ORM, параметризованные запросы и шаблонизаторы с авто-экранированием сделали частый путь безопасным по умолчанию, поэтому средняя частота упала, даже когда категория расширилась, поглотив XSS. Урок: риск падает в рейтинге, когда безопасный вариант становится лёгким вариантом — ровно тот исход, к которому стремится хороший дизайн.
Как сеньор читает список
Рейтинг — это инструмент приоритизации, а не евангелие. Сеньор читает его как «где моё время потрачено лучше всего», и контроль доступа выигрывает по ожидаемой ценности: это самый частый класс и один из самых разрушительных, поэтому он заслуживает наибольшей строгости — серверные проверки на каждый объект и каждую функцию, написанные как deny-by-default. Остальное считай картой покрытия: крипта в транзите и в покое, параметризованный доступ к данным, процесс обновления зависимостей, чтобы A06 не накапливался молча, ужесточённые конфиги и структурное логирование безопасности, чтобы вообще обнаружить взлом, который не предотвратил.
Endpoint `GET /api/invoices/{id}` возвращает счёт по id. Пользователь меняет id в URL и видит чужой счёт. Выбери правильный фикс.
Почему «Sensitive Data Exposure» переименовали в «Cryptographic Failures» в 2021?
Не-админ шлёт `POST /api/admin/users/7/promote` напрямую, и это срабатывает, хотя кнопка админа спрятана в его UI. Что это за категория и каков фикс?
Расставь категории Top 10 2021 по рангу, от A01 до A05:
- 1 Broken Access Control (94% приложений; IDOR + пропуск authz)
- 2 Cryptographic Failures (переименован из Sensitive Data Exposure)
- 3 Injection (теперь включает XSS; опустился с #1)
- 4 Insecure Design (новая — threat-model до кода)
- 5 Security Misconfiguration (дефолтные креды, болтливые ошибки)
- 01Объясни, почему Broken Access Control прыгнул на #1 в 2021 и что значит «deny by default» в коде.
- 02Чем особенны Insecure Design и SSRF и почему их появление в 2021 сигнализирует о взрослении области?
OWASP Top 10 (2021) — это основанный на данных рейтинг категорий риска, собранный из 500 000+ реальных приложений и реорганизованный вокруг корневых причин вместо симптомов — поэтому «Sensitive Data Exposure» стал «Cryptographic Failures». Broken Access Control — заглавная история: он поднялся с #5 на #1, встречается в 94% протестированных приложений и проявляется в продакшене как IDOR и отсутствие авторизации на уровне функции. Фикс — авторизация deny-by-default, проверяемая на сервере на каждом объекте и действии, никогда не выводимая из спрятанной кнопки или присланного клиентом claim. Две новые категории эпохи проектирования — Insecure Design и SSRF — отмечают взросление области от «фильтруй плохой ввод» к «проектируй под least privilege», причём SSRF заслужил своё место голосом практиков несмотря на тонкие исторические данные. Читай список как карту приоритетов: трать больше всего строгости там, где ожидаемый ущерб выше, а остальное держи как покрытие, которому не даёшь дрейфовать.