Подготовка безопасности приложений Django Rest Framework для производства (Auth и Admin Panel)

Intro

Я создал веб-приложение с несколькими службами:

  • фронтенд (react)
  • backend (API и административная панель) (Django Rest Framework + простой jwt auth)
  • Redis, DB, Nginx и т.д.
  • Kubernetes кластер

Приложение не маленькое, как 60k+ строк кода. Это стартап. Я упомянул это, чтобы вы знали, что, вероятно, я не буду иметь столько внимания от хакеров или трафика вообще. Поэтому у меня есть пространство для постепенного улучшения.

Аутентификация осуществляется с помощью простой jwt библиотеки DRF. Истекающий доступ + токен Refresh.

Заявление о проблеме

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

Фактический список вопросов

Давайте ссылаться на его номер, если хотите.

#1 Методы аутентификации

Моя текущая установка:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
    .....

}

Как вы видите, у меня есть 3 метода. JWT в порядке, но BasicAuthentication и SessionAuthentication, похоже, не в порядке. Я хочу добиться того, чтобы настоящий JWT аутентификатор был единственным способом аутентификации для API представлений (и я действительно верил, что у меня это получилось, пока не узнал обратное).

Как я понял (могу ошибаться), мне не нужны SessionAuthentication и BasicAuthentication в производственной установке, но нужны для dev, потому что это позволяет мне войти в DRF API UI с помощью формы входа, что очень удобно для тестирования. Я прав?

#2 Сессии

Когда я добрался до Chrome Dev Tools и проверил куки, я был обескуражен. На данный момент я отказался от SessionAuthentication и BasicAuthentication как для теста.

enter image description here

Как я понял, у меня есть куки с идентификатором сессии из-за SessionMiddleware. И это нормально, потому что он используется только для аутентификации в админ панели и игнорируется представлениями DRF API так что единственным способом аутентификации является JWT но так ли это? Возможно, это может иметь больше последствий и эксплойтов. Следовательно, должен ли я полностью отказаться от SessionMiddleware, особенно для достижения цели иметь JWT auth как единственный тип аутентификации?

* Я понимаю, что это приведет к отказу от возможности использовать функцию панели администратора, и я рассмотрю этот вопрос позже.

#3 Я храню токены Access и Refresh в локальном хранилище

Да, похоже, я не прав. Я признаю это. Это был недостаток опыта в начале. Фронтенд приложение и тесты (я использую Cypress) сильно зависят от токенов, которые должны быть в локальном хранилище, но это осуществимо для миграции. С другой стороны, я просто боюсь новых ошибок, которые могут появиться после этого. Кроме того, я подозреваю, что миграция может быть немного болезненной. Вопрос в том, насколько это критично, и, следовательно, должен ли я мигрировать хранилище токенов на куки сейчас или могу сделать это позже?

#4.1 Отделение панели администратора от API

Django Admin panel - это потрясающе, мы все знаем, но она тесно связана с приложением. Но проблема №2 привела меня к идее разделить API и Admin. Так как я использую Kubernetes, идея состоит в том, чтобы запустить два сервиса. Один - API, я представляю его как ту же кодовую базу, но настройки разные (отключенные SessionMiddlware и админ-панель). И другой сервис, где функция админ-панели полностью включена. Имеет ли это смысл?

* Мне кажется, что это немного попахивает чрезмерной инженерией. Поэтому, пожалуйста, остановитесь, если я ошибаюсь в этом.

** Похоже, что это сильно зависит от #2, потому что если нет проблем и эксплойтов с SessionMiddleware, следовательно, нет веских причин делать это.

#4.2 Настройка производства панели администратора

Мне просто интересно, каковы лучшие практики безопасности для настройки доступа к панели администратора в prod. У меня абсолютно пустая настройка. Никакой капчи. Никаких VPN. Полностью ванильная. И вопрос в том, какова наиболее реальная, но эффективная настройка доступа? Я чувствую, что это должно быть как-то защищено. По крайней мере, /admin не должен быть публичной конечной точкой (VPN?), но я понятия не имею, как этого добиться. Я на Google Cloud Platform, так что, возможно, я могу использовать одно из ее решений?

Аутро

Какие еще проверки безопасности вы проводите перед выходом на производство в качестве инженера? То есть, конечно, лучший способ - нанять команду безопасности, но я не могу этого сделать

Что я сделал:

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

Спасибо, Артем

#1 Да, удалите оба других метода авторизации и оставьте только jwt auth, это только для фреймворка REST, поэтому не должно быть проблемой для /admin.

#2 Первые пункты уже решают эту проблему. Но помните, что вы также можете изменять пути к cookies из django. Таким образом, вы можете установить, что /admin в вашем django приложении использует другие cookies. Это позволит вам полностью отделить /admin от других урлов вашего приложения. Вы найдете это интересным:

SESSION_COOKIE_PATH = '/admin'
CSRF_COOKIE_PATH = '/admin'
LANGUAGE_COOKIE_PATH = '/admin'
SESSION_COOKIE_NAME = 'backend-sessionid'
CSRF_COOKIE_NAME = 'backend-csrftoken'

#3 Насколько я знаю... это единственный способ сохранить токены во внешнем приложении. Таким образом, безопасность там обеспечивается за счет наличия "срока действия" токенов, в случае если кто-то получит токены от клиента, он будет иметь доступ только в течение короткого периода времени. Это во многом зависит от логики работы предприятия и от того, как вы хотите управлять истечением срока действия

#4.1 Я не рекомендую запускать ваше приложение в двух экземплярах, вы должны уметь правильно настроить приложение и избегать подобных решений.

#4.2 Как вы упомянули, /admin должен иметь ограниченный доступ. Я сделал это с помощью белых списков IP (это можно сделать на nginx), но вам придется знать IP заранее. Вы также можете сделать это с помощью http auth в nginx, чтобы у вас был пользователь и пароль (которые вы можете разделить без необходимости знать IP), запрашиваемые еще до подключения к приложению django.

Рекомендации:

  • Запустите сканирование вашего приложения, например: https://observatory.mozilla.org/ Это позволит вам узнать много других вещей безопасности, которые вам понадобятся в вашем приложении. С этим вы должны быть готовы чувствовать себя в безопасности. И еще, бывает, что вы не можете избежать провала некоторых тестов, просто постарайтесь сделать лучше, чтобы уменьшить проблемы.
  • .
Вернуться на верх