Безопасное хранение и передача секретов (токенов, паролей и т.п.) между пользователями и сервисами – это один из вызовов, с которыми сталкиваются разработчики и DevOps инженеры. Традиционное централизованное хранение в менеджерах паролей, например, полностью проблему не решает, а лишь смещает её в сторону управления мастер-паролями, которые, к тому же, становятся «ключами к царству» и компроментация которых может иметь катастрофические последствия. Данную проблему «курицы и яйца» ещё иногда называют проблемой «нулевого секрета» (Secret Zero Problem). В этой заметке я расскажу о попытке решить эту проблему при помощи механизма обёртки ответа (Response Wrapping).

Для повышения безопасности мы не будем передавать секреты напрямую, мы будем передавать лишь ссылку на секрет - обёрточный токен (Wrapping Token). Сам секрет будет храниться в безопасности, в специализированной системе управления секретами (Secrets Management Service). Повышение безопасности обеспечивается за счет ряда полезных свойств токена, а именно:

  1. Обëрточный токен — это не секрет сам по себе, а лишь ссылка, дающяя доступ к настоящему секрету

  2. Токен может (и должен!) обладать очень коротким временем жизни (TTL – Time to Live), что делает атаку на подобную «движущуюся цель» более сложной

  3. И, наконец, если злоумышленник перехватит токен и всё-таки заполучит секрет, то это будет немедленно обнаружено. Во-первых, обëрточный токен может быть использован только один раз, после чего он «протухает», а во-вторых - система управления секретами обеспечивает надёжный аудит всех действий пользователей

Функционал Response Wrapping обеспечивают многие решения по управлению секретами. Рассмотрим практический пример на примере популярного HashiCorp Vault. В нашем простейшем сценарии у нас есть Vault сервис, и нам нужно передать учётные данные вида пользователь/пароль удалённому пользователю или сервису, который ничего не знает о Vault и никак с ним не интегрирован. Vault можно легко установить и настроить или воспользоваться SaaS сервисом. Коммуницировать с Vault можно напрямую через API, Vault CLI или Web UI. Чтобы начать работать через CLI, на стороне администратора необходимо задать пару переменных окружения:

Адрес Vault сервера, пусть в нашем примере он будет локальный

export VAULT_ADDR=http://127.0.0.1:8200

Администраторский токен доступа к Vault

export VAULT_TOKEN="hvs.CAESIJT1q5lEjIWux1Tjx"

Vault поддерживает великое множество различных плагинов (engines), для приведённого примера нам понадобится самый базовый – хранение Key/Value (KV) пар.

Активируем плагин KV:

$ vault secrets enable -path=secret -description="wraper-test" kv-v2 

В нашем упражнении мы создадим и передадим удаленному клиенту секрет вида

username: "webapp"

password: "my-long-password"

запишем наш секрет используя включённый KV плагин:

$ vault kv put secret/dev username="webapp" password="my-long-password"

Теперь создадим wrapper token c TTL 2 минуты. Этого времени должно быть достаточно, чтоб клиент успел извлечь секрет из Vault:

$ vault kv get -wrap-ttl=120 secret/dev

Вариант ответа:

Key Value
--- -----
wrapping_token: hvs.CAGh2cy5uYzZsZEMpiR25LZXpjczA

wrapping_accessor: 3dyFk8GHlmLNvKEjxcL9TDz2
wrapping_token_ttl: 2m
wrapping_token_creation_time: 2022-04-05 21:09:08.2289 -0700 PDT wrapping_token_creation_path: secret/data/dev

Полученный wrapping_tokenмы можем передать получателю при помощи e-mail или в чате, особо не беспокоясь о возможном перехвате. Наш клиент, как помним, ничего не знает о Vault, но, надеемся, обладает базовыми навыками в Unix shell и может воспользоваться командами curl и jq. При помощи указанных команд, адреса Vault $VAULT_ADDR и полученного токена, извлечь секрет из Vault проще простого:

$ curl -s --header "X-Vault-Token: hvs.CAGh2cy5uYzZsZEMpiR25LZXpjczA" --request POST $VAULT_ADDR/v1/sys/wrapping/unwrap | jq ".data.data"

Результат на стороне клиента:

{

"password": "my-long-password",

"username": "webapp"

}

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

Комментарии (4)


  1. dyadyaSerezha
    11.11.2022 10:31
    +1

    Данную проблему «курицы и яйца»

    Проблемы нет и ответ очевиден - яйцо было первым.

    А вообще, пароль отдаётся в ответе http, перехватывается и всё начинается снова. То есть, передача пароля от нашей системы клиенту сменилась на передачу пароля от Vault клиенту. Так себе преимущество. Вот если бы сам разовый токен использовался для авторизации вместо username/password, было бы гораздо лучше.


    1. sloniki Автор
      11.11.2022 10:49
      +3

      То есть, передача пароля от нашей системы клиенту сменилась на передачу пароля от Vault клиенту. Так себе преимущество.

      Проблема не решена полностью, но поверхность атаки уменьшена.

      Вот если бы сам разовый токен использовался для авторизации вместо username/password, было бы гораздо лучше.

      А кому токен давать? Всё равно вопрос аутентификации актуален. Ну и разумеется, генерация коротких токенов - это основная фишка решений типа Vault. Здесь рассмотрен предельно упрощённый сценарий.


  1. halfblood23
    13.11.2022 17:57

    А как вообще vault поставить, если он заблокирован в России?


    1. sloniki Автор
      13.11.2022 17:59
      +1

      Заблокирован полагаю SaaS. А скачать OpenSource версию должно быть несложно через VPN.