Безопасное хранение учетных данных в python

Атака

Одной из возможных моделей угроз в контексте хранения учетных данных является злоумышленник, который имеет возможность:

  • проверить любую (пользовательскую) память процесса
  • читать локальные (пользовательские) файлы

AFAIK, консенсус по этому типу атаки заключается в невозможности предотвратить (поскольку учетные данные должны храниться в памяти, чтобы программа фактически их использовала), но есть несколько способов смягчения этого:

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

Python в частности

Первый метод достаточно прост для реализации, возможно через брелок (надеюсь, хранилище пространства ядра)

Второе не достижимо вообще без написания C-модуля, насколько мне известно (но я бы хотел, чтобы это было неправильно здесь или имело список существующих модулей)

Третий сложный.

В частности, python является языком с очень мощными возможностями самоанализа и отражения, трудно предотвратить доступ к учетным данным любому, кто может выполнять код python в процессе интерпретации.

Похоже, существует консенсус в отношении того, что нет способа принудительного использования частных атрибутов и что попытки на него в лучшем случае будут раздражать другие программисты, которые используют ваш код.

Вопрос

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

Ответ 1

Существуют две разные причины, по которым вы можете хранить учетные данные для проверки подлинности:

  • Чтобы выполнить аутентификацию пользователя: например, вы разрешаете пользователю доступ к службам после того, как пользователь будет аутентифицирован в вашей программе.
  • Чтобы выполнить аутентификацию программы с помощью другой программы или службы: например, пользователь запускает вашу программу, которая затем обращается к электронной почте пользователя через Интернет с помощью протокола IMAP.

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

Во втором случае, чтобы сделать секретное обнаружение сложнее (как вы начертите в своем вопросе), например:

  • Сохранение секретов зашифровано до тех пор, пока не понадобится, дешифрование по требованию, а затем повторное шифрование сразу после
  • Использование рандомизации адресного пространства, поэтому каждый раз, когда приложение запускается, ключи хранятся с другим адресом
  • Использование хранилищ ОС
  • Использование "жесткого" языка, такого как C/С++, а не основанного на VM, интроспективного языка, такого как Java или Python

Такие подходы, конечно, лучше, чем ничего, но опытный хакер рано или поздно сломает его.

Жетоны

С теоретической точки зрения аутентификация является доказательством того, что лицо, оспорено, является тем, кем они себя называют. Традиционно это достигается с помощью общей секретности (пароль), но есть другие способы доказать себя, в том числе:

  • Out-of-band. Например, когда я живу, когда я пытаюсь войти в свой интернет-банк, я получаю одноразовый пароль (OTP) в качестве SMS-сообщения на своем телефоне. В этом методе я доказываю, что я являюсь владельцем определенного номера телефона.
  • Маркер безопасности: Чтобы войти в службу, я должен нажать кнопку на своем токене, чтобы получить OTP, который затем я использую в качестве пароля.
  • Другие устройства:

    • SmartCard, в частности, используется Министерством США, где он называется CAC. Python имеет модуль под названием pyscard, чтобы взаимодействовать с этим
    • устройство NFC

И более полный список здесь

Общность между всеми этими подходами заключается в том, что конечный пользователь контролирует эти устройства, и секреты никогда не оставляют токен/карту/телефон и, безусловно, никогда не сохраняются в вашей программе. Это делает их намного более безопасными.

Воровство сеансов

Однако (всегда есть):

Предположим, вам удастся защитить логин, чтобы хакер не смог получить доступ к маркерам безопасности. Теперь ваше приложение успешно взаимодействует с защищенным сервисом. К сожалению, если хакер может выполнять произвольные исполняемые файлы на вашем компьютере, хакер может захватить ваш сеанс, например, путем ввода дополнительных команд в ваше действительное использование службы. Другими словами, несмотря на то, что вы защитили пароль, это совершенно не имеет значения, поскольку хакер все еще получает доступ к "защищенному" ресурсу.

Это очень реальная угроза, так как многократные атаки с межсайтовыми сценариями показывают (один пример Учетные данные в США и Банке Америки уязвимы, но есть бесчисленное множество).

Защищенный прокси

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

Один из способов частично смягчить это, делегируя связь службе безопасному прокси и разработайте безопасный подход входа между приложением и прокси. При таком подходе

  • Приложение использует схему PKI или двухфакторную аутентификацию для входа в защищенный прокси
  • Пользователь добавляет учетные данные безопасности сторонней системе в защищенный прокси. Учетные данные никогда не сохраняются в приложении
  • Позже, когда приложение должно получить доступ к сторонней системе, оно отправляет запрос прокси. Прокси регистрируется при использовании учетных данных безопасности и делает запрос, возвращая результаты в приложение.

К недостаткам этого подхода относятся:

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

Некоторые ответы

Итак, по конкретным ответам:

Как безопасно хранить учетные данные аутентификации с помощью python?

  • Если вы сохраняете пароль для аутентификации пользователя, используйте алгоритм PBKDF2, например https://www.dlitz.net/software/python-pbkdf2/
  • Если вы храните маркер пароля/безопасности для доступа к другой службе, то нет абсолютно безопасного способа.
  • Однако рассмотрите возможность переключения стратегий аутентификации на, например, смарт-карту, используя, например, pyscard. Вы можете использовать смарт-карты для аутентификации пользователя в приложении, а также для надежной аутентификации приложения в другой службе с сертификатами X.509.

Можно ли что-то сделать с языком "все публично"? Я знаю, что "мы все соглашаемся с взрослыми здесь", но нужно ли нам выбирать между тем, чтобы делиться нашими паролями с нападавшим и использовать другой язык?

ИМХО, нет ничего плохого в написании конкретного модуля в Python, который делает это чертовски, чтобы скрыть секретную информацию, что делает его правильным педерастом для повторного использования другими (раздражает других программистов - его цель). Вы даже можете закодировать большие части в C и ссылку на него. Однако не делайте этого для других модулей по понятным причинам.

В конечном счете, если хакер контролирует компьютер, на компьютере вообще нет конфиденциальности. Теоретический худший случай заключается в том, что ваша программа запущена на виртуальной машине, и хакер имеет полный доступ ко всей памяти на компьютере, включая BIOS и графическую карту, и может направить ваше приложение на проверку подлинности, чтобы открыть его секреты.

Без абсолютной конфиденциальности, остальное - просто обфускация, а уровень защиты - это просто то, насколько сложно запутаться, насколько опытный хакер хочет получить информацию. И мы все знаем, как что заканчивается, даже для настраиваемого оборудования и миллиардные продукты.

Использование ключа Python

Хотя это будет достаточно безопасно управлять ключом по отношению к другим приложениям, все приложения Python будут иметь доступ к токенам. Это не в малейшей степени защищено от типа атаки, о которой вы беспокоитесь.

Ответ 2

Я не эксперт в этой области, и я действительно просто ищу решение той же проблемы, что и вы, но это похоже на что-то вроде Hashicorp Vault может быть очень полезен.

В частности, WRT относится к проблеме хранения учетных данных для служб третьей части. например:

В современном мире, управляемом API, многие системы также поддерживают программное создание учетных данных доступа. Vault использует эту поддержку благодаря функции, называемой динамическими секретами: секреты, которые генерируются по требованию, а также поддерживают автоматическое аннулирование.

В Vault 0.1 Vault поддерживает динамическое генерирование учетных данных AWS, SQL и Consul.

Другие ссылки: