демистификация колбы приложение.секретный ключ

Если app.secret_key не установлен, Flask не позволит вам установить или получить доступ к словарю сеанса.

Это все Flask руководство пользователя должно сказать на эту тему.

Я очень новичок в веб-разработке, и я понятия не имею, как/почему работает любой материал безопасности. Хотелось бы понять, что фляжка делает под капотом.

  • почему Фласк заставляет нас установить это secret_key собственность?
  • как колба использует secret_key собственность?

2 ответов


все, что требует шифрования (для обеспечения безопасности от взлома злоумышленниками), требует установки секретного ключа. Для просто фляжка сама по себе, что "ничего" является Session object, но другие расширения могут использовать тот же секрет.

secret_key - это просто значение, установленное для SECRET_KEY ключ настройки, или вы можете установить его непосредственно.

на раздел сеансов в Quickstart имеет хороший, здравый совет о том, какой серверный секрет вы должны установить.

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

фляга использует itsdangerous библиотека для выполнения всей тяжелой работы; сеансы используют itsdangerous.URLSafeTimedSerializer класс С настроенным сериализатором JSON.


ответ ниже относится в первую очередь к Подписанные Cookies реализация концепции сеансы (как используется в веб-приложениях). Flask предлагает как обычные (без знака) cookies (via request.cookies и response.set_cookie()) и подписанные cookies (через flask.session). Ответ состоит из двух частей, первая описывает, как генерируется подписанный файл Cookie, а вторая представлена в виде QA, который обращается к различным аспектам схемы. Синтаксис, используемый для примеров является Python3, но понятия применимы и к предыдущим версиям.

что это SECRET_KEY (или как создать подписанный файл Cookie)?

подписание файлов cookie является превентивной мерой против подделки файлов cookie. В процессе подписания файла cookie SECRET_KEY используется аналогично тому, как" соль " будет использоваться для путаницы пароля перед его хэшированием. Вот (дико) упрощенное описание концепции. Код в примерах должен быть иллюстративным. Многие шаги были опущены, и не все функции фактически существуют. Цель здесь состоит в том, чтобы обеспечить понимание общей идеи, фактические реализации будут немного более задействованы. Кроме того, имейте в виду, что фляга действительно это для вас в фоновом режиме. Итак, помимо установки значений для вашего cookie (через API сеанса) и предоставления SECRET_KEY, не только не рекомендуется переосмысливать это самостоятельно, но и нет необходимости делать это:

печенье бедняка подпись

перед отправкой ответа в браузер:

(1 ) Сначала a это. Он должен быть известен только приложению и должен оставаться относительно постоянным в течение жизненного цикла приложения, в том числе путем перезапуска приложения.

# choose a salt, a secret string of bytes
>>> SECRET_KEY = 'my super secret key'.encode('utf8')

(2 ) Создайте cookie

>>> cookie = make_cookie(
...     name='_profile', 
...     content='uid=382|membership=regular',
...     ...
...     expires='July 1 2030...'
... )

>>> print(cookie)
name: _profile
content: uid=382|membership=regular...
    ...
    ...
expires: July 1 2030, 1:20:40 AM UTC

(3) чтобы создать подпись, добавьте (или добавьте)SECRET_KEY в строку байта cookie, затем создайте хэш из этого сочетание.

# encode and salt the cookie, then hash the result
>>> cookie_bytes = str(cookie).encode('utf8')
>>> signature = sha1(cookie_bytes+SECRET_KEY).hexdigest()
>>> print(signature)
7ae0e9e033b5fa53aa....

(4) Теперь прикрепите подпись на одном конце content поле исходного файла cookie.

# include signature as part of the cookie
>>> cookie.content = cookie.content + '|' + signature
>>> print(cookie)
name: _profile
content: uid=382|membership=regular|7ae0e9...  <--- signature
domain: .example.com
path: /
send for: Encrypted connections only
expires: July 1 2030, 1:20:40 AM UTC

и это то, что отправляется клиенту.

# add cookie to response
>>> response.set_cookie(cookie)
# send to browser --> 

после получения cookie из браузера:

(5)когда браузер возвращает этот файл cookie обратно на сервер, удалите подпись изcontent поле для возврата исходного файла cookie.

# Upon receiving the cookie from browser
>>> cookie = request.get_cookie()
# pop the signature out of the cookie
>>> (cookie.content, popped_signature) = cookie.content.rsplit('|', 1)

( 6 ) использовать оригинальный cookie с приложением SECRET_KEY пересчитать подпись с помощью того же метода, что и на Шаге 3.

# recalculate signature using SECRET_KEY and original cookie
>>> cookie_bytes = str(cookie).encode('utf8')
>>> calculated_signature = sha1(cookie_bytes+SECRET_KEY).hexdigest()

( 7 ) сравните вычисленный результат с подписью, ранее выскочившей из только что полученного файла cookie. Если они совпадают, мы знаем, что печенье не испортил. Но если даже просто пробел был добавлен в cookie, подписи не будут совпадать.

# if both signatures match, your cookie has not been modified
>>> good_cookie = popped_signature==calculated_signature

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

>>> if not good_cookie:
...     security_log(cookie)

хэш-код аутентификации сообщений (HMAC)

тип подписи, сгенерированный выше, который требует секретного ключа для обеспечения целостности некоторого содержимого, называется в криптографии a Код Аутентификации Сообщения или MAC.

ранее я указывал, что приведенный выше пример является упрощением этой концепции и что она не было хорошей идеей реализовать собственную подпись. Это потому, что алгоритм, используемый для подписания куки-файлов в колбе, называется HMAC и немного более вовлечен, чем вышеупомянутый простой шаг за шагом. Общая идея та же, но по причинам, выходящим за рамки этого обсуждения, серия вычислений немного сложнее. Если вы все еще заинтересованы в создании DIY, как это обычно бывает, Python имеет несколько модулей, которые помогут вам начать работу :) вот начало блок:

import hmac
import hashlib

def create_signature(secret_key, msg, digestmod=None):
    if digestmod is None:
        digestmod = hashlib.sha1
    mac = hmac.new(secret_key, msg=msg, digestmod=digestmod)
    return mac.digest()

документ для hmac и hashlib.


"демистификация"SECRET_KEY :)

что такое "подпись" в данном контексте?

это метод для обеспечения того, чтобы некоторый контент не был изменен кем-либо, кроме лица или организации, уполномоченной на это.

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

предположим, например, что вы собираетесь загрузить источник проекта в gzipped файл из веб-зеркала. Контрольная сумма SHA1, опубликованная на веб-странице проекта, является " eb84e8da7ca23e9f83....'

# so you get the code from the mirror
download https://mirror.example-codedump.com/source_code.tar.gz
# you calculate the hash as instructed
sha1(source_code.tar.gz)
> eb84e8da7c....

оба хэша одинаковы, вы знаете, что у вас есть идентичная копия.

что такое печенье?

обширное обсуждение cookies выходит за рамки этого вопроса. Я предоставляю обзор здесь, так как минимальное понимание может быть полезно для лучшего понимания того, как и почему SECRET_KEY полезно. Я настоятельно рекомендую вам следить за некоторыми личными чтениями http-файлов Cookies.

обычной практикой в веб-приложениях является использование клиента (веб-браузера) в качестве легкого кэша. Cookies-одна из реализаций этой практики. Cookie-это обычно некоторые данные, добавленные сервером в http-ответ через его заголовки. Он хранится браузером, который впоследствии отправляет его обратно на сервер при выдаче запросов, также через HTTP-заголовки. Данные, содержащиеся в cookie можно использовать для эмуляции того, что называется контроль изменения состояния, иллюзия, что сервер поддерживает постоянное соединение с клиентом. Только в этом случае вместо провода, чтобы сохранить соединение "живым", у вас просто есть снимки состояния приложения после того, как оно обработало запрос клиента. Эти моментальные снимки переносятся между клиентом и сервером. После получения запроса, сервер сначала считывает содержимое файла cookie, чтобы восстановить контекст его разговора с клиентом. Затем он обрабатывает запрос в этом контексте и перед возвращением ответа клиенту обновляет файл cookie. Таким образом, сохраняется иллюзия продолжающейся сессии.

как выглядит печенье?

типичный файл cookie будет выглядеть следующим образом:

name: _profile
content: uid=382|status=genie
domain: .example.com
path: /
send for: Encrypted connections only
expires: July 1 2030, 1:20:40 AM UTC

Cookies тривиальны для просмотра из любого современного браузера. В Firefox например,Настройки > Конфиденциальность > История > удалить отдельные куки.

на content поле является наиболее актуальным для приложения. Другие поля содержат в основном мета-инструкции для указания различных областей влияния.

зачем вообще использовать cookies?

короткий ответ: производительность. Используя cookies, минимизирует необходимость поиска в различных хранилищах данных (кэшах памяти, файлах, базах данных и т. д.), Тем самым ускоряя работу серверного приложения сторона. Имейте в виду, что чем больше cookie, тем тяжелее полезная нагрузка по сети, поэтому то, что вы сохраняете в поиске базы данных на сервере, вы можете потерять по сети. Внимательно подумайте,что включить в cookies.

зачем нужно подписывать cookies?

Cookies используются для хранения всех видов информации, некоторые из которых могут быть очень чувствительными. Они также по своей природе не безопасны и требуют, чтобы ряд вспомогательных мер предосторожности принято считать безопасной в любом случае для обеих сторон, клиента и сервера. Подписание куки-файлов специально решает проблему, с которой они могут быть обработаны в попытках обмануть серверные приложения. Есть и другие меры по смягчению других типов уязвимостей, я рекомендую вам прочитать больше о cookies.

как можно подделать печенье?

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

почему SECRET_KEY необходимо подписать печенье?

проверка файлов cookie немного отличается от проверки исходного кода, как это описано ранее. В случае исходного кода исходный автор является доверенным лицом и владельцем контрольного отпечатка пальца (контрольной суммы), который будет храниться в открытом доступе. Вы не доверяете исходному коду, но доверяете публичной подписи. Поэтому для проверки вашей копии источника вы просто хотите, чтобы ваш вычисленный хэш соответствовал общедоступному хэшу.

в случае файл cookie, однако приложение не отслеживает подпись, оно отслеживает его SECRET_KEY. The SECRET_KEY ссылка отпечатков пальцев. Cookies путешествуют с подписью, которую они утверждают, что являются законными. Легитимность здесь означает, что подпись была выдана владельцем файла cookie, то есть приложения, и в этом случае это утверждение, которому вы не доверяете, и вам нужно проверить подпись на действительность. Для этого вам нужно включить в подпись элемент, который известен только ты, это SECRET_KEY. Кто-то может изменить печенье, но так как у них нет секретного ингредиента, чтобы правильно вычислить действительную подпись, они не могут подделать его. Как было сказано немного ранее, этот тип отпечатков пальцев, где поверх контрольной суммы также предоставляется секретный ключ, называется кодом аутентификации сообщения.

насчет сессий?

сеансы в их классической реализации являются cookies, которые несут только идентификатор в content поле session_id. Цель сеансов точно такая же, как подписанные куки, т. е. предотвратить подделку файлов cookie. Однако классические сеансы имеют другой подход. После получения файла cookie сеанса сервер использует идентификатор для поиска данных сеанса в собственном локальном хранилище, которое может быть базой данных, файлом или иногда кэшем в памяти. Файл cookie сеанса обычно имеет срок действия при закрытии браузера. Из-за шага поиска локального хранилища эта реализация сеансов как правило, снижает производительность. Подписанные файлы cookie становятся предпочтительной альтернативой, и именно так реализуются сеансы Flask. Другими словами, сеансы колбы are подписанные куки, и использовать подписанные куки в колбе просто использовать его Session API-интерфейс.

почему бы также не зашифровать файлы cookie?

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

что произойдет, если я изменю SECRET_KEY?

изменение SECRET_KEY ты опровергаешь все cookies, подписанные предыдущим ключом. Когда приложение получает запрос с файлом cookie, который был подписан с предыдущим SECRET_KEY, он попытается вычислить подпись с новым SECRET_KEY, и обе подписи не будут совпадать, этот файл cookie и все его данные будут отклонены, это будет как если бы браузер подключался к серверу в первый раз. Пользователи будут выходить из системы, а их старые файлы cookie будут забыты вместе со всем, что хранится внутри. Обратите внимание, что это отличается от способа обработки файла cookie с истекшим сроком действия. Файл cookie с истекшим сроком действия может иметь его аренда продлевается, если его подпись подтверждается. Недопустимая подпись подразумевает просто недопустимый файл cookie.

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

что такое хороший SECRET_KEY?

секретный ключ должен быть трудно угадываемым. Документация по сеансы имеет хороший рецепт для генерации случайных ключей:

>>> import os
>>> os.urandom(24)
'\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8'

скопировать ключ и вставьте его в файл конфигурации как значение SECRET_KEY.

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

Do не установить SECRET_KEY непосредственно с функцией, которая генерирует другой ключ каждый раз это называется. Например, не делайте этого:

# this is not good
SECRET_KEY = random_key_generator()

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

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