Безопасный куки
Предупреждение
Устарело начиная с версии 0.15: Будет удалено в версии 1.0. Перемещено в https://github.com/pallets/secure-cookie.
werkzeug.contrib.securecookie
Этот модуль реализует куки, который нельзя изменить со стороны клиента, потому что он добавляет контрольную сумму, которую сервер проверяет. Его можно использовать в качестве замены сессий, если у вас есть только идентификатор пользователя или что-то, чтобы отметить вошедшего пользователя.
Обратите внимание, что данные по-прежнему читаются клиентом как обычный куки. Однако вам не нужно хранить и сбрасывать сессии на сервере.
Пример использования:
>>> from werkzeug.contrib.securecookie import SecureCookie
>>> x = SecureCookie({"foo": 42, "baz": (1, 2, 3)}, "deadbeef")
Выгрузка в строку, чтобы можно было сохранить её в куки:
>>> value = x.serialize()
Загрузка из этой строки снова:
>>> x = SecureCookie.unserialize(value, "deadbeef") >>> x["baz"] (1, 2, 3)
Если кто-то изменяет куки, а контрольная сумма неверна, метод unserialize проигнорирует это и вернёт новый пустой SecureCookie объект.
Обратите внимание, что значения будут видны в куки, поэтому не храните в куки данные, которые вы не хотите, чтобы пользователь видел.
Интеграция в приложение
Если вы используете объекты запроса werkzeug, вы можете интегрировать безопасный куки в своё приложение так:
from werkzeug.utils import cached_property
from werkzeug.wrappers import BaseRequest
from werkzeug.contrib.securecookie import SecureCookie
# don't use this key but a different one; you could just use
# os.urandom(20) to get something random
SECRET_KEY = '\xfa\xdd\xb8z\xae\xe0}4\x8b\xea'
class Request(BaseRequest):
@cached_property
def client_session(self):
data = self.cookies.get('session_data')
if not data:
return SecureCookie(secret_key=SECRET_KEY)
return SecureCookie.unserialize(data, SECRET_KEY)
def application(environ, start_response):
request = Request(environ)
# get a response object here
response = ...
if request.client_session.should_save:
session_data = request.client_session.serialize()
response.set_cookie('session_data', session_data,
httponly=True)
return response(environ, start_response)
Более лаконичная интеграция может быть достигнута с помощью сокращённых методов:
class Request(BaseRequest):
@cached_property
def client_session(self):
return SecureCookie.load_cookie(self, secret_key=COOKIE_SECRET)
def application(environ, start_response):
request = Request(environ)
# get a response object here
response = ...
request.client_session.save_cookie(response)
return response(environ, start_response)
Безопасность
По умолчанию используется Pickle, так как это единственный модуль, который был доступен в стандартной библиотеке при создании этого модуля. Если доступен simplejson, настоятельно рекомендуется создать подкласс и заменить метод сериализации:
import json
from werkzeug.contrib.securecookie import SecureCookie
class JSONSecureCookie(SecureCookie):
serialization_method = json
Слабостью Pickle является то, что если кто-то получит доступ к секретному ключу, злоумышленник не только сможет изменить сессию, но и выполнить произвольный код на сервере.
Справочник
-
Представляет собой безопасный куки. Вы можете создать подкласс этого класса и предоставить альтернативный метод mac. Важно, что метод mac — это функция с интерфейсом, похожим на hashlib. Требуемые методы — update() и digest().
Пример использования:
>>> x = SecureCookie({"foo": 42, "baz": (1, 2, 3)}, "deadbeef") >>> x["foo"] 42 >>> x["baz"] (1, 2, 3) >>> x["blafasel"] = 23 >>> x.should_save TrueПараметры: -
data – начальные данные. Либо словарь, список кортежей или
None. -
secret_key – секретный ключ. Если не задан
None, или не указан, он должен быть установлен перед вызовомserialize(). -
new – начальное значение флага
new.
-
True, если куки был только что создан, иначеFalse.
-
Всякий раз, когда устанавливается элемент в куки, этот атрибут устанавливается в
True. Однако это не отслеживает изменения внутри изменяемых объектов в куки:>>> c = SecureCookie() >>> c["foo"] = [1, 2, 3] >>> c.modified True >>> c.modified = False >>> c["foo"].append(4) >>> c.modified False
В такой ситуации он должен быть установлен в
modified, чтобыshould_saveмог его получить.
-
Метод хэширования для использования. Он должен быть модулем с новой функцией или функцией, создающей объект hashlib. Например,
hashlib.md5. Подклассы могут переопределять этот атрибут. По умолчанию используется sha1. Убедитесь, что вы обернули это в staticmethod(), если вы храните произвольную функцию, такую как hashlib.sha1, которая может быть реализована как функция.
-
Загружает
SecureCookieиз куки в запросе. Если куки не установлен, возвращается новый экземплярSecureCookie.Параметры: -
request – объект запроса, у которого есть атрибут
cookies, который является словарем всех значений куки. - key – имя куки.
- secret_key – секретный ключ, используемый для расшифровки куки. Всегда указывайте значение, даже если у него нет значения по умолчанию!
-
request – объект запроса, у которого есть атрибут
-
Приводит значение к виду, подходящему для куки. Это может быть любой объект, поддерживаемый
serialization_method.Параметры: value – значение для обработки.
-
Если содержимое должно быть закодировано в base64. Это можно отключить, если процесс сериализации возвращает только строки, безопасные для куки.
-
Сохраняет SecureCookie в куки в объекте ответа. Все параметры, которые здесь не описаны, передаются напрямую в
set_cookie().Параметры: -
response – объект ответа, у которого есть метод
set_cookie(). - key – имя куки.
-
session_expires – дата истечения срока действия безопасных данных куки. Если это не указано, используется дата куки
expires.
-
response – объект ответа, у которого есть метод
-
Модуль, используемый для сериализации. Должен иметь методы
dumpsиloads, принимающие байты. По умолчаниюpickle.Изменено в версии 0.15: Значение по умолчанию
pickleбудет изменено наjsonв версии 1.0.
-
Сериализует безопасный куки в строку.
Если expires указано, сессия будет автоматически аннулирована после истечения срока действия при её десериализации. Это обеспечивает лучшую защиту от кражи куки сессии.
Параметры: expires – необязательная дата истечения срока действия куки (объект datetime.datetime)
-
Расшифровывает значение куки. Если расшифровка не удаётся, генерируется исключение
UnquoteError.Параметры: value – значение для расшифровки.
-
Загружает безопасный куки из сериализованной строки.
Параметры: - string – значение куки для десериализации.
- secret_key – секретный ключ, используемый для сериализации куки.
Возвращает: новый
SecureCookie.
-
data – начальные данные. Либо словарь, список кортежей или
-
Внутреннее исключение, используемое для обозначения ошибок при обработке.
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://werkzeug.palletsprojects.com/en/0.15.x/contrib/securecookie/