демістифікувати колбу app.secret_key


127

Якщо app.secret_keyйого не встановлено, Flask не дозволить вам встановити або отримати доступ до словника сеансу.

Це все, що посібник користувача колби має сказати з цього приводу.

Я дуже новачок у веб-розробці, і не маю уявлення, як / чому працює якийсь захист. Я хотів би зрозуміти, що Flask робить під кришкою.

  • Чому Flask змушує нас встановити цю secret_keyвластивість?
  • Як Flask використовує secret_keyмайно?

Відповіді:


102

Все, що вимагає шифрування (для безпечного зберігання від зловмисників) вимагає встановлення секретного ключа. Для тільки самого Колба, що «все» є Sessionоб'єктом, але і інші розширення можуть використовувати той же секрет.

secret_keyце лише значення, встановлене для SECRET_KEYключа конфігурації, або ви можете встановити його безпосередньо.

У розділі " Сесії" у "Швидкому старті" є хороші, здорові поради щодо того, який секрет на стороні сервера ви повинні встановити.

Шифрування покладається на секрети; якби ви не встановили секрет на стороні сервера для використання шифрування, усі змогли б порушити ваше шифрування; це як пароль до комп'ютера. Секрет плюс дані для означення використовуються для створення рядка підпису, важко відтворити значення за допомогою алгоритму криптографічного хешування ; тільки якщо у вас є абсолютно однакова таємниця та вихідні дані, ви зможете відтворити це значення, дозволяючи Flask виявляти, якщо щось було змінено без дозволу. Оскільки секрет ніколи не включається до даних, яку Flask надсилає клієнту, клієнт не може підробити дані сеансу і сподіватися створити новий, дійсний підпис.

Flask використовує itsdangerousбібліотеку для виконання всіх важких робіт; сеанси використовують itsdangerous.URLSafeTimedSerializerклас із спеціалізованим серіалізатором JSON.


91

Відповідь нижче стосується в основному підписаних файлів cookie - реалізації концепції сеансів (як це використовується у веб-додатках). Flask пропонує як звичайні (непідписані) файли cookie (через request.cookiesта response.set_cookie()), так і підписані файли cookie (через flask.session). Відповідь складається з двох частин, перша описує, як створюється підписане печиво, а друга подається у формі якості, яка стосується різних аспектів схеми. Синтаксис, який використовується для прикладів, є Python3, але поняття стосуються також і попередніх версій.

Що таке SECRET_KEY(чи як створити підписаний файл cookie)?

Підписання файлів cookie є запобіжним заходом проти фальсифікації файлів cookie. Під час підписання файлу cookie SECRET_KEYвикористовується так, як "сіль" буде використовуватися для заблуднення пароля перед його хешированием. Ось (дико) спрощений опис концепції. Код у прикладах повинен бути ілюстративним. Багато етапів було опущено, і не всі функції існують насправді. Мета тут - дати розуміння загальної ідеї, реальні реалізації будуть задіяні трохи більше. Також майте на увазі, що Flask робить для вас більшу частину цього у фоновому режимі. Отже, окрім встановлення значень для файлу cookie (за допомогою API сеансу) та надання файлу SECRET_KEY, не лише радимо повторно виконувати це, але й робити це не потрібно:

Підпис печива бідного чоловіка

Перш ніж надсилати відповідь веб-переглядачу:

(1) Спочатку a SECRET_KEYвстановлюється. Він повинен бути відомий лише програмі та повинен підтримуватися відносно постійним протягом життєвого циклу програми, в тому числі шляхом перезавантаження програми.

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

(2) створити печиво

>>> 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 назад на сервер, зніміть підпис з поля 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 не був заблокований. Але якщо до файлу cookie було додано навіть просто пробіл, підписи не збігаються.

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

(8) Якщо вони не відповідають, ви можете відповісти будь-якою кількістю дій, зареєструвати подію, відмовитись від файлів cookie, видати свіжий, перенаправити на сторінку входу тощо.

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

Код автентифікації повідомлень на основі хеша (HMAC)

Тип генерованого вище підпису, для якого потрібен секретний ключ, щоб забезпечити цілісність деякого вмісту, в криптографії називається кодом автентифікації повідомлення або MAC .

Раніше я зазначив, що приклад, наведений вище, - це надмірне спрощення цієї концепції і що не дуже вдало реалізувати власне підписання. Це тому, що алгоритм, який використовується для підписання файлів cookie у Flask, називається HMAC і є дещо більш задіяним, ніж описаний вище простий крок за кроком. Загальна ідея така ж, але через причини, що виходять за рамки цієї дискусії, ряд обчислень є набагато складнішим. Якщо ви все ще зацікавлені в тому, щоб створити саморобку, як це зазвичай буває, у 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 та хешлібу .


"Демістифікація" 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....

Обидва хеші однакові, ви знаєте, що у вас є ідентична копія.

Що таке печиво?

Широка дискусія щодо файлів cookie вийде за межі цього питання. Я надаю огляд тут, оскільки мінімальне розуміння може бути корисним, щоб краще зрозуміти, як і навіщо SECRET_KEYкорисно. Я настійно рекомендую вам ознайомитися з деякими особистими читаннями на HTTP Cookies.

Поширена практика у веб-додатках - використовувати клієнт (веб-браузер) як легкий кеш. Файли cookie - це одна реалізація цієї практики. Файл 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

Файли cookie банально використовувати для будь-якого сучасного веб-переглядача. Наприклад, у Firefox перейдіть до Налаштування> Конфіденційність> Історія> видаліть окремі файли cookie .

contentПоле є найбільш значущим для застосування. Інші поля містять в основному мета інструкції, щоб вказати різні сфери впливу.

Навіщо взагалі використовувати файли cookie?

Коротка відповідь - це продуктивність. Використання файлів cookie мінімізує необхідність пошуку речей у різних сховищах даних (кеш пам'яті, файлів, баз даних тощо), тим самим прискорюючи роботи на стороні серверної програми. Майте на увазі, що чим більший розмір файлу cookie, тим важче корисне навантаження по мережі, тому те, що ви зберігаєте при пошуку бази даних на сервері, ви можете втратити через мережу. Подумайте уважно, що потрібно включити у файли cookie.

Чому печиво потрібно підписувати?

Файли cookie використовуються для зберігання всілякої інформації, частина якої може бути дуже чутливою. Вони також за своєю природою не є безпечними і вимагають вжити ряд допоміжних запобіжних заходів, щоб будь-яким чином вважатись безпечним для обох сторін, клієнта та сервера. Підписання файлів cookie вирішує проблему, з якою їх можна вирішити, намагаючись обдурити серверні програми. Існують і інші заходи щодо зменшення вразливості інших типів, я закликаю вас прочитати більше про файли cookie.

Як можна підробити печиво?

Файли cookie знаходяться на клієнті в текстовій формі і їх можна редагувати без особливих зусиль. Файли cookie, отримані вашою серверною програмою, могли бути змінені з кількох причин, деякі з яких можуть бути невинними. Уявіть веб-додаток, який зберігає інформацію про дозвіл своїх користувачів на файлах cookie та надає пільги на основі цієї інформації. Якщо файл cookie не є захищеним від посилань, кожен може змінити свій статус, щоб підвищити його статус з "role = відвідувач" на "role = admin", і програма не була б мудрішою.

Чому SECRET_KEYпотрібно підписувати файли cookie?

Перевірка файлів cookie є дещо іншою, ніж перевірка вихідного коду так, як це описано раніше. Що стосується вихідного коду, то оригінальним автором є довірена особа та власник опорного відбитка пальця (контрольної суми), який буде публічним. Те, що ви не довіряєте, - це вихідний код, але ви довіряєте публічному підпису. Отже, щоб підтвердити свою копію джерела, ви просто хочете, щоб ваш обчислений хеш відповідав загальнодоступному хешу.

Що стосується файлу cookie, програма не відслідковує підпис, вона відслідковує її SECRET_KEY. Це SECRET_KEYопорний відбиток. Файли cookie розміщуються з підписом, який вони вважають законним. Легітимність тут означає, що підпис видав власник файлу cookie, тобто додаток, і в цьому випадку це те ствердження, що ви не довіряєте, і вам потрібно перевірити підпис на дійсність. Для цього вам потрібно включити елемент у підпис, який вам відомий, саме це SECRET_KEY. Хтось може змінити печиво, але оскільки у них немає секретного інгредієнта, щоб правильно обчислити дійсний підпис, він не може підробити його. Як було сказано трохи раніше, цей тип відбитків пальців, де поверх контрольної суми, також є секретний ключ,

Що з сесіями?

Сесії в їх класичній реалізації - це файли cookie, що містять у contentполі лише ідентифікатор , the session_id. Мета сеансів точно така ж, як і підписані файли cookie, тобто запобігання підробці файлів cookie. Однак класичні заняття мають інший підхід. Після отримання файлу cookie сеансу сервер використовує ідентифікатор для пошуку даних сеансу у власній локальній пам’яті, яка може бути базою даних, файлом або іноді кешем пам’яті. Зазвичай сеансовий файл cookie встановлюється, коли браузер закриється. Через крок пошуку локальної пам’яті, ця реалізація сеансів зазвичай спричиняє показник ефективності. Підписані файли cookie стають бажаною альтернативою, і саме так реалізуються сесії Flask. Іншими слова, колби сесія єпідписані файли cookie, а щоб використовувати підписані файли cookie у Flask, просто використовуйте його SessionAPI.

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

Іноді вміст файлів cookie можна зашифрувати до того, як вони також будуть підписані . Це робиться, якщо вони вважаються занадто чутливими, щоб бути видимими у браузері (шифрування приховує вміст). Однак, просто підписуючи файли cookie, вирішується інша потреба, яка потребує збереження певної видимості та зручності використання файлів cookie у веб-переглядачі, не допускаючи того, щоб вони могли бути порушені.

Що станеться, якщо я поміняю SECRET_KEY?

Змінивши SECRET_KEYви недійсні всі файли cookie, підписані попереднім ключем. Коли програма отримає запит із файлом cookie, який був підписаний з попереднім SECRET_KEY, він спробує обчислити підпис з новим SECRET_KEY, і обидва підписи не збігаються, цей файл cookie та всі його дані будуть відхилені, це буде як би браузер підключається до сервера вперше. Користувачі вийдуть із системи, і їх старий файл 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.

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

Ви НЕ встановити SECRET_KEYбезпосередньо з функцією , яка генерує інший ключ кожен раз , коли він називається. Наприклад, не робіть цього:

# this is not good
SECRET_KEY = random_key_generator()

Кожен раз, коли ваша програма перезапускається, їй буде наданий новий ключ, таким чином недійсний попередній.

Замість цього відкрийте інтерактивну оболонку пітона та зателефонуйте до функції, щоб створити ключ, а потім скопіюйте та вставте його у конфігурацію.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.