2016-12-27 3 views
1

Я пытаюсь понять, как работает токен flask-security. У меня есть секретный ключ в моей конфигурации flask, но наш код является открытым исходным кодом и в python, так что это не очень секретно.Как создаются маркеры безопасности?

У меня есть возможность в коде доступа к сериалайзеру, который создал маркер:

serializer = current_app.extensions['security'].remember_token_serializer 

И тогда я могу сделать serializer.loads(token) и получить имя пользователя и хэш пароля.

Итак, мой вопрос заключается в следующем: что мешает злоумышленнику прослушивать мой трафик, который имеет секретный ключ, делать то же самое - получать маркер токенов серий и десериализовать мой токен? Есть ли какая-то другая соль, которую использует flask при создании жетонов? Но тогда, как бы он расшифровал токен, если служба должна была перезапуститься?

ответ

2

Я не совсем уверен в деталях реализации и том, как создается токен (но я уверен, что флеш-защита использует itsdangerous).

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

Маркер используется для передачи данных из одного источника (клиента) к другому (сервер) и убедитесь, что данные не Modified или изменено любым

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

Вот краткий демо о том, что я имею в виду, используя itsdangerous (Колба сама использует эту библиотеку для сеансов)

Давайте предположим, что в вашем приложении вы только предоставить доступ администратора пользователям, проверяя, если они имеют набор параметров is_admin до 'true' в токене.

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

from itsdangerous import URLSafeSerializer 

>>> s = URLSafeSerializer('secret key') 
>>> s.dumps({'username': 'john', 'is_admin': 'false'}) 
'eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6ImZhbHNlIn0.k45WPrVOG1Nrags0bwpVUbS7Vcw' 

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

import base64 
>>> base64.b64decode('eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6ImZhbHNlIn0===') 
b'{"username":"john","is_admin":"false"}' 

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

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

Поскольку он не наш сервер в секрете, он просто использует случайный секрет

>>> t = URLSafeSerializer('fake key') 
>>> t.dumps({'username': 'john', 'is_admin': 'true'}) 
'eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6InRydWUifQ.fPUeGmfSaQWCysy5WWTmmMeuo6c' 

Хорошо, тогда он посылает маркер на наш сервер.

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

>>> s.loads('eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6InRydWUifQ.fPUeGmfSaQWCysy5WWTmmMeuo6c') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/danidee/venv/lib/python3.5/site-packages/itsdangerous.py", line 582, in loads 
    return self.load_payload(self.make_signer(salt).unsign(s)) 
    File "/home/danidee/venv/lib/python3.5/site-packages/itsdangerous.py", line 374, in unsign 
    payload=value) 
itsdangerous.BadSignature: Signature b'fPUeGmfSaQWCysy5WWTmmMeuo6c' does not match 
>>> 

Сервер может проверять только токены, которые были подписаны с помощью ключа, который он имеет. Если ваш серверный ключ не был взломан, вам не нужно беспокоиться о том, чтобы кто-либо отправлял измененные данные в ваше приложение.

Вы только должны удостовериться, что вы не храните «реальные секреты» в маркере

# We can always load the correct token back 
s.loads('eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6ImZhbHNlIn0.k45WPrVOG1Nrags0bwpVUbS7Vcw') 
{'username': 'john', 'is_admin': 'false'} 

Даже если вы пытаетесь прикрепить подпись справа знак на неправильные данные не будут действительным, и вы все равно получите ошибку

s.loads('eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6InRydWUifQ.k45WPrVOG1Nrags0bwpVUbS7Vcw') 

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/danidee/venv/lib/python3.5/site-packages/itsdangerous.py", line 582, in loads 
    return self.load_payload(self.make_signer(salt).unsign(s)) 
    File "/home/danidee/venv/lib/python3.5/site-packages/itsdangerous.py", line 374, in unsign 
    payload=value) 
itsdangerous.BadSignature: Signature b'k45WPrVOG1Nrags0bwpVUbS7Vcw' does not match 

Отказ от ответственности: Это может быть не точной реализации в безопасности опоки, но мой ответ должен дать вам представление о том, что происходит за кулисами. Вы также можете прочитать JSON web tokens

и не хранить ваши секреты в своем конфигурационном файле, сохранить его в .env (который не будет частью контроля источника) или сделать его переменной окружения и EXPORT/SET переменная в производственной среде.

Оформить заказ dotenv

+1

благодарит за отличный ответ! Это делает проблему намного яснее. Теперь я понимаю, что нам нужно перевести секретный ключ в файл конфигурации или env var. – mcouthon

Смежные вопросы