По фреймворкам
Безопасность ASP.NET Core — справочник по продакшн-хардингу
Справочник по продакшн-хардингу ASP.NET Core: приоритетный чек-лист плюс ошибки в проде, секреты (User Secrets/Key Vault), CVE NuGet, авторизация, over-posting, десериализация и SSRF. Защитно, без шагов атаки.
Для: всех, кто ведёт приложение или API на ASP.NET Core. Здесь нет шагов атаки — это рабочий справочник по хардингу: приоритетный чек-лист, руководство по областям и самопроверка. Полную картину по фреймворкам смотрите на хабе безопасности по фреймворкам.
Приоритетный чек-лист хардинга
Проходите эту таблицу сверху вниз. P0 — предпосылка, P1 — самый частый источник инцидентов, P2 — постоянная эксплуатационная гигиена.
P0 ── Предпосылка (сначала это)
Никаких детальных ошибок в проде / вынос секретов наружу / быстрое закрытие CVE зависимостей NuGet
P1 ── Главный источник инцидентов
Авторизация ([Authorize], запрет по умолчанию, владелец) / защита от over-posting (DTO/[Bind])
P2 ── Эксплуатационная гигиена
Небезопасная десериализация / HTTPS, заголовки, antiforgery / SSRF
| Приоритет | Мера | Конкретика (ASP.NET Core) |
|---|---|---|
| P0 | Ошибки в проде | UseExceptionHandler. Не показывайте Developer Exception Page/детали в проде (корректная проверка окружения) |
| P0 | Вынос секретов наружу | Не зашивайте в appsettings.json. Разработка = User Secrets, прод = окружение/Key Vault |
| P0 | CVE зависимостей NuGet | Мониторьте через dotnet list package --vulnerable/osv-scanner; судите по запущенной версии, быстро закрывайте |
| P1 | Явная авторизация | [Authorize] + запрет по умолчанию (fallback-политика) + ресурсные/владельческие проверки |
| P1 | Защита от over-posting | Привязывайте к DTO, а не к сущности напрямую. Используйте [Bind] для ограничения принимаемых полей |
| P2 | Десериализация | Не используйте BinaryFormatter. Не восстанавливайте недоверенные данные небезопасным форматом |
| P2 | HTTPS/заголовки/CSRF | UseHttpsRedirection, UseHsts, antiforgery (CSRF), атрибуты cookie |
| P2 | SSRF | Список разрешённых для серверных запросов + блокировка внутренних IP/метаданных |
1. Раскрытие ошибок в проде (P0)
- В продакшене переключайтесь на общую ошибку через
UseExceptionHandlerи не показывайте Developer Exception Page/детали (корректно настройте проверку окружения, напримерASPNETCORE_ENVIRONMENT=Production). - Не давайте утекать трассировкам стека или внутренней структуре вовне.
2. Вынос секретов наружу (P0)
- Не зашивайте строки подключения или ключи в appsettings.json. Используйте User Secrets в разработке и переменные окружения или облачный менеджер секретов (Key Vault) в проде.
- appsettings.json легко утекает через случайный коммит или экспозицию. Не коммитьте его в репозиторий и не помещайте в публичный каталог (→ не держите секреты в публичных каталогах). Оперативно ротируйте при утечке.
3. CVE зависимостей NuGet (P0)
- Машинно мониторьте известные CVE через
dotnet list package --vulnerableили osv-scanner, судите по запущенной версии и быстро закрывайте (→ мониторинг CVE зависимостей · плейбук реагирования на уязвимости). - Держите .NET на поддерживаемой версии и не оставляйте EOL-версии.
4. Авторизация (P1 — главный источник)
Частое (опасное)
- забыт
[Authorize]на эндпоинте - аутентифицирован, но нет проверки владельца
- значение по умолчанию склонено к «разрешить», неаутентифицированные проходят
- нет проектирования ролей/политик, разрозненные проверки
Правильно
[Authorize]+ запрет по умолчанию через fallback-политику- ролевая/политиковая + ресурсная авторизация для владения
- проверено на каждом пути чтения/обновления/удаления
- авторизация построена явно, а не оставлена на значения по умолчанию
Смотрите что такое IDOR. Аутентификация и авторизация различны; авторизуйте близко к данным.
5. Over-posting (P1)
- Не привязывайте сущности напрямую. Привязывайте к входному DTO и принимайте только нужные поля.
- Или используйте
[Bind], чтобы явно ограничить принимаемые поля. Не давайте перезаписать флаг привилегии из внешнего ввода.
6. Небезопасная десериализация и ввод (P2)
- Не используйте
BinaryFormatter(устарел/небезопасен). Не восстанавливайте недоверенные данные небезопасным форматом (при определённых условиях может привести к RCE) (→ что такое RCE). - Проверяйте ввод через валидацию модели (data annotations и т. п.) — тип/диапазон/допустимые значения — перед использованием.
7. HTTPS, заголовки, antiforgery (P2)
- Используйте
UseHttpsRedirection+UseHsts, чтобы принудительно включить HTTPS, и помечайте cookie как secure/httponly/samesite. - Используйте токены antiforgery (защита от CSRF) на формах/запросах, меняющих состояние (→ что такое CSRF).
- Добавьте заголовки безопасности (проверьте свой сайт через проверку заголовков безопасности).
8. SSRF и серверные запросы (P2)
- Серверная (
HttpClientи т. п.) выборка URL, заданных пользователем, должна ограничивать цели списком разрешённого и блокировать доступ к внутренним IP/метаданным (→ что такое SSRF). Проверяйте загрузки и храните их вне публичной зоны.
Проверьте: действительно ли ваш ASP.NET Core укреплён?
Собрать — ещё не конец: работа сделана только после проверки. Это защитные самопроверки против собственной среды.
Нет Developer Exception Page в проде
Секретов нет в конфигурации/репозитории
appsettings.json и что секретов нет в репозитории.Авторизация держится
Зависимости и HTTPS/заголовки
dotnet list package --vulnerable/osv чист и что HTTPS/HSTS присутствуют — через проверку заголовков.Взгляд нашего сайта: даже на надёжной основе настройки и авторизация на вас
У ASP.NET Core надёжные механизмы аутентификации, авторизации и защиты данных, но продакшн-настройки и применение авторизации вы должны выставить правильно для каждой среды и каждого эндпоинта. Наш сайт на другом стеке, но принцип тот же: не раскрывайте внутренности в проде, держите секреты вне конфигурации, всегда пишите авторизацию на публичных точках входа и мониторьте зависимости на CVE. Надёжная основа окупается лишь при корректных настройках и явной авторизации.
Читать дальше
- Хаб: безопасность по фреймворкам · безопасность Spring Boot (тоже enterprise, похожая форма зависимостей/авторизации)
- Практика: плейбук реагирования на уязвимости · мониторинг CVE зависимостей · не держите секреты в публичных каталогах
- Глоссарий: что такое IDOR · что такое RCE · CSRF · SSRF
- Инструменты: проверка заголовков безопасности
FAQ
QЧто сделать в первую очередь для защиты ASP.NET Core?
Три пункта P0: (1) не показывайте Developer Exception Page / детальные ошибки в проде (UseExceptionHandler, корректная проверка окружения); (2) выносите секреты наружу вместо жёсткого кодирования в appsettings.json (User Secrets в разработке, переменные окружения или Key Vault в проде); (3) машинно мониторьте CVE зависимостей NuGet и быстро закрывайте, судя по запущенной версии. Дальше переходите к авторизации ([Authorize], запрет по умолчанию) и защите от over-posting.
QГде должны храниться секреты (строки подключения, ключи API)?
Правило: не зашивать в appsettings.json. В разработке используйте User Secrets; в проде загружайте из переменных окружения или облачного менеджера секретов (Key Vault). appsettings.json склонен попадать в репозиторий и легко утекает через публичный каталог или случайный коммит. Если что-то утекло, оперативно ротируйте строку подключения или ключ.
QКак не забывать атрибуты авторизации?
Забудьте [Authorize] на контроллере или эндпоинте — и до него сможет добраться любой без аутентификации. Склоните значение по умолчанию к запрету (fallback-политика, отклоняющая неаутентифицированные запросы), делайте права явными через ролевую/политиковую авторизацию и пишите проверки владельца ресурса (ресурсная авторизация). Не останавливайтесь на «залогинен = можно» — проверяйте и владельца объекта.
QЧто такое over-posting?
Если model binding принимает каждое поле в сущность, непредвиденные поля, отправленные пользователем (например, флаг привилегии), могут быть перезаписаны — это over-posting. Исправление — привязка к входному DTO или использование [Bind] для явного ограничения принимаемых полей. Не привязывайте сущности напрямую.
QПочему небезопасная десериализация опасна?
Восстановление недоверенных данных небезопасным десериализатором вроде BinaryFormatter при определённых условиях может привести к удалённому выполнению кода (RCE). BinaryFormatter считается устаревшим/небезопасным — не используйте его. Проверяйте происхождение данных из внешних источников и при необходимости ограничивайтесь безопасным форматом (например, правильно настроенным JSON).