Spec-Zone.ru › Werkzeug 0.15

Безопасный куки

Предупреждение

Устарело начиная с версии 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 является то, что если кто-то получит доступ к секретному ключу, злоумышленник не только сможет изменить сессию, но и выполнить произвольный код на сервере.

Справочник

class werkzeug.contrib.securecookie.SecureCookie(data=None, secret_key=None, new=True)

Представляет собой безопасный куки. Вы можете создать подкласс этого класса и предоставить альтернативный метод 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.
new

True, если куки был только что создан, иначе False.

modified

Всякий раз, когда устанавливается элемент в куки, этот атрибут устанавливается в True. Однако это не отслеживает изменения внутри изменяемых объектов в куки:

>>> c = SecureCookie()
>>> c["foo"] = [1, 2, 3]
>>> c.modified
True
>>> c.modified = False
>>> c["foo"].append(4)
>>> c.modified
False

В такой ситуации он должен быть установлен в modified, чтобы should_save мог его получить.

static hash_method()

Метод хэширования для использования. Он должен быть модулем с новой функцией или функцией, создающей объект hashlib. Например, hashlib.md5. Подклассы могут переопределять этот атрибут. По умолчанию используется sha1. Убедитесь, что вы обернули это в staticmethod(), если вы храните произвольную функцию, такую как hashlib.sha1, которая может быть реализована как функция.

classmethod load_cookie(request, key='session', secret_key=None)

Загружает SecureCookie из куки в запросе. Если куки не установлен, возвращается новый экземпляр SecureCookie.

Параметры:
  • request – объект запроса, у которого есть атрибут cookies, который является словарем всех значений куки.
  • key – имя куки.
  • secret_key – секретный ключ, используемый для расшифровки куки. Всегда указывайте значение, даже если у него нет значения по умолчанию!
classmethod quote(value)

Приводит значение к виду, подходящему для куки. Это может быть любой объект, поддерживаемый serialization_method.

Параметры: value – значение для обработки.
quote_base64 = True

Если содержимое должно быть закодировано в base64. Это можно отключить, если процесс сериализации возвращает только строки, безопасные для куки.

save_cookie(response, key='session', expires=None, session_expires=None, max_age=None, path='/', domain=None, secure=None, httponly=False, force=False)

Сохраняет SecureCookie в куки в объекте ответа. Все параметры, которые здесь не описаны, передаются напрямую в set_cookie().

Параметры:
  • response – объект ответа, у которого есть метод set_cookie().
  • key – имя куки.
  • session_expires – дата истечения срока действия безопасных данных куки. Если это не указано, используется дата куки expires.
serialization_method = <module 'pickle' from '/home/docs/.pyenv/versions/3.7.3/lib/python3.7/pickle.py'>

Модуль, используемый для сериализации. Должен иметь методы dumps и loads, принимающие байты. По умолчанию pickle.

Изменено в версии 0.15: Значение по умолчанию pickle будет изменено на json в версии 1.0.

serialize(expires=None)

Сериализует безопасный куки в строку.

Если expires указано, сессия будет автоматически аннулирована после истечения срока действия при её десериализации. Это обеспечивает лучшую защиту от кражи куки сессии.

Параметры: expires – необязательная дата истечения срока действия куки (объект datetime.datetime)
should_save

True, если сессия должна быть сохранена. По умолчанию это верно только для куки modified, а не new.

classmethod unquote(value)

Расшифровывает значение куки. Если расшифровка не удаётся, генерируется исключение UnquoteError.

Параметры: value – значение для расшифровки.
classmethod unserialize(string, secret_key)

Загружает безопасный куки из сериализованной строки.

Параметры:
  • string – значение куки для десериализации.
  • secret_key – секретный ключ, используемый для сериализации куки.
Возвращает:

новый SecureCookie.

exception werkzeug.contrib.securecookie.UnquoteError

Внутреннее исключение, используемое для обозначения ошибок при обработке.

© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://werkzeug.palletsprojects.com/en/0.15.x/contrib/securecookie/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API