From c3188340e841633924e8ab7a055c1df0dffed9c1 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 16 Sep 2018 11:06:05 -0500 Subject: deprecate pickleable sessions, recommend json --- docs/narr/sessions.rst | 72 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 19 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 2d80b1a63..17e8291a0 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -59,25 +59,59 @@ using the :meth:`pyramid.config.Configurator.set_session_factory` method. By default the :func:`~pyramid.session.SignedCookieSessionFactory` implementation contains the following security concerns: - - Session data is *unencrypted*. You should not use it when you keep - sensitive information in the session object, as the information can be - easily read by both users of your application and third parties who have - access to your users' network traffic. - - - If you use this sessioning implementation, and you inadvertently create a - cross-site scripting vulnerability in your application, because the - session data is stored unencrypted in a cookie, it will also be easier for - evildoers to obtain the current user's cross-site scripting token. - - - The default serialization method, while replaceable with something like - JSON, is implemented using pickle which can lead to remote code execution - if your secret key is compromised. - - In short, use a different session factory implementation (preferably one - which keeps session data on the server) for anything but the most basic of - applications where "session security doesn't matter", you are sure your - application has no cross-site scripting vulnerabilities, and you are confident - your secret key will not be exposed. + - Session data is *unencrypted* (but it is signed / authenticated). + + This means an attacker cannot change the session data, but they can view it. + You should not use it when you keep sensitive information in the session object, as the information can be easily read by both users of your application and third parties who have access to your users' network traffic. + + At the very least, use TLS and set ``secure=True`` to avoid arbitrary users on the network from viewing the session contents. + + - If you use this sessioning implementation, and you inadvertently create a cross-site scripting vulnerability in your application, because the session data is stored unencrypted in a cookie, it will also be easier for evildoers to obtain the current user's cross-site scripting token. + + Set ``httponly=True`` to mitigate this vulnerability by hiding the cookie from client-side JavaScript. + + - The default serialization method, while replaceable with something like JSON, is implemented using pickle which can lead to remote code execution if your secret key is compromised. + + To mitigate this, set ``serializer=pyramid.session.JSONSerializer()`` to use :class:`pyramid.session.JSONSerializer`. This option will be the default in :app:`Pyramid` 2.0. + See :ref:`pickle_session_deprecation` for more information about this change. + + In short, use a different session factory implementation (preferably one which keeps session data on the server) for anything but the most basic of applications where "session security doesn't matter", you are sure your application has no cross-site scripting vulnerabilities, and you are confident your secret key will not be exposed. + +.. _pickle_session_deprecation: + +Upcoming Changes to ISession in Pyramid 2.0 +------------------------------------------- + +In :app:`Pyramid` 2.0 the :class:`pyramid.interfaces.ISession` interface will be changing to require that session implementations only need to support json-serializable data types. +This is a stricter contract than the current requirement that all objects be pickleable and it is being done for security purposes. +This is a backward-incompatible change. +Currently, if a client-side session implementation is compromised, it leaves the application vulnerable to remote code execution attacks using specially-crafted sessions that execute code when deserialized. + +For users with compatibility concerns, it's possible to craft a serializer that can handle both formats until you are satisfied that clients have had time to reasonably upgrade. +Remember that sessions should be short-lived and thus the number of clients affected should be small (no longer than an auth token, at a maximum). An example serializer: + +.. code-block:: python + :linenos: + + from pyramid.session import JSONSerializer + from pyramid.session import PickleSerializer + + class JSONSerializerWithPickleFallback(object): + def __init__(self): + self.json = JSONSerializer() + self.pickle = PickleSerializer() + + def dumps(self, value): + # maybe catch serialization errors here and keep using pickle + # while finding spots in your app that are not storing + # json-serializable objects, falling back to pickle + return self.json.dumps(value) + + def loads(self, value): + try: + return self.json.loads(value) + except ValueError: + return self.pickle.loads(value) .. index:: single: session object -- cgit v1.2.3 From 38bbea331f9c485d40892a17674272a8876a55a1 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 16 Sep 2018 15:43:43 -0500 Subject: tweak some docs --- docs/narr/sessions.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 17e8291a0..971b4502d 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -79,10 +79,13 @@ using the :meth:`pyramid.config.Configurator.set_session_factory` method. .. _pickle_session_deprecation: +.. index:: + triple: pickle deprecation; JSON-serializable; ISession interface + Upcoming Changes to ISession in Pyramid 2.0 ------------------------------------------- -In :app:`Pyramid` 2.0 the :class:`pyramid.interfaces.ISession` interface will be changing to require that session implementations only need to support json-serializable data types. +In :app:`Pyramid` 2.0 the :class:`pyramid.interfaces.ISession` interface will be changing to require that session implementations only need to support JSON-serializable data types. This is a stricter contract than the current requirement that all objects be pickleable and it is being done for security purposes. This is a backward-incompatible change. Currently, if a client-side session implementation is compromised, it leaves the application vulnerable to remote code execution attacks using specially-crafted sessions that execute code when deserialized. @@ -104,7 +107,7 @@ Remember that sessions should be short-lived and thus the number of clients affe def dumps(self, value): # maybe catch serialization errors here and keep using pickle # while finding spots in your app that are not storing - # json-serializable objects, falling back to pickle + # JSON-serializable objects, falling back to pickle return self.json.dumps(value) def loads(self, value): @@ -173,7 +176,7 @@ Some gotchas: that they are instances of basic types of objects, such as strings, lists, dictionaries, tuples, integers, etc. If you place an object in a session data key or value that is not pickleable, an error will be raised when the - session is serialized. + session is serialized. Please also see :ref:`pickle_session_deprecation`. - If you place a mutable value (for example, a list or a dictionary) in a session object, and you subsequently mutate that value, you must call the -- cgit v1.2.3 From 07207637818049d27abb90792d48d7ed8fdd2340 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 16 Sep 2018 22:45:05 -0500 Subject: ref after index apparently --- docs/narr/sessions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 971b4502d..d4d3c1074 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -77,11 +77,11 @@ using the :meth:`pyramid.config.Configurator.set_session_factory` method. In short, use a different session factory implementation (preferably one which keeps session data on the server) for anything but the most basic of applications where "session security doesn't matter", you are sure your application has no cross-site scripting vulnerabilities, and you are confident your secret key will not be exposed. -.. _pickle_session_deprecation: - .. index:: triple: pickle deprecation; JSON-serializable; ISession interface +.. _pickle_session_deprecation: + Upcoming Changes to ISession in Pyramid 2.0 ------------------------------------------- -- cgit v1.2.3 From 0296259599809671df9a4bb3b14623c117c09344 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 22 Sep 2018 01:33:35 -0700 Subject: Update links to trypyramid.com, Grok, gunicorn --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 3ee6b5367..9293386f2 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -52,7 +52,7 @@ Modern Tested ~~~~~~ -Untested code is broken by design. The :app:`Pyramid` community has a strong testing culture and our framework reflects that. Every release of :app:`Pyramid` has 100% statement coverage (as measured by `coverage `_) and 95% decision/condition coverage. (as measured by `instrumental `_) It is automatically tested using `Travis `_ and `Jenkins `_ on supported versions of Python after each commit to its GitHub repository. `Official Pyramid add-ons `_ are held to a similar testing standard. +Untested code is broken by design. The :app:`Pyramid` community has a strong testing culture and our framework reflects that. Every release of :app:`Pyramid` has 100% statement coverage (as measured by `coverage `_) and 95% decision/condition coverage. (as measured by `instrumental `_) It is automatically tested using `Travis `_ and `Jenkins `_ on supported versions of Python after each commit to its GitHub repository. `Official Pyramid add-ons `_ are held to a similar testing standard. We still find bugs in :app:`Pyramid`, but we've noticed we find a lot fewer of them while working on projects with a solid testing regime. @@ -173,7 +173,7 @@ Supported :app:`Pyramid` add-ons are held to the same demanding standards as the .. seealso:: - See also https://trypyramid.com/resources-extending-pyramid.html + See also https://trypyramid.com/extending-pyramid.html Write your views, *your* way ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 97ee7f3aa8af74a01e51c0c14fda1c0a5a490663 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 25 Sep 2018 15:49:23 -0500 Subject: show how to use the serializer --- docs/narr/sessions.rst | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index d4d3c1074..ded7e87e3 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -98,6 +98,7 @@ Remember that sessions should be short-lived and thus the number of clients affe from pyramid.session import JSONSerializer from pyramid.session import PickleSerializer + from pyramid.session import SignedCookieSessionFactory class JSONSerializerWithPickleFallback(object): def __init__(self): @@ -116,6 +117,11 @@ Remember that sessions should be short-lived and thus the number of clients affe except ValueError: return self.pickle.loads(value) + # somewhere in your configuration code + serializer = JSONSerializerWithPickleFallback() + session_factory = SignedCookieSessionFactory(..., serializer=serializer) + config.set_session_factory(session_factory) + .. index:: single: session object -- cgit v1.2.3 From f9c3ff6db52f107f298852b92ecc945fbc26229c Mon Sep 17 00:00:00 2001 From: Paul Cutler Date: Wed, 3 Oct 2018 10:06:48 -0500 Subject: Change references to "py.test" in narrative documentation Change reference of "py.test" to "pytest" per pytest 3.0 release in the project and testing pages of narrative documentation --- docs/narr/project.rst | 24 ++++++++++++------------ docs/narr/testing.rst | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index fb5a241db..a15138207 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -239,26 +239,26 @@ On Windows: %VENV%\Scripts\pip install -e ".[testing]" Once the testing requirements are installed, then you can run the tests using -the ``py.test`` command that was just installed in the ``bin`` directory of +the ``pytest`` command that was just installed in the ``bin`` directory of your virtual environment. On Unix: .. code-block:: bash - $VENV/bin/py.test -q + $VENV/bin/pytest -q On Windows: .. code-block:: doscon - %VENV%\Scripts\py.test -q + %VENV%\Scripts\pytest -q Here's sample output from a test run on Unix: .. code-block:: bash - $VENV/bin/py.test -q + $VENV/bin/pytest -q .. 2 passed in 0.47 seconds @@ -266,28 +266,28 @@ The tests themselves are found in the ``tests.py`` module in your ``cookiecutter .. note:: - The ``-q`` option is passed to the ``py.test`` command to limit the output + The ``-q`` option is passed to the ``pytest`` command to limit the output to a stream of dots. If you don't pass ``-q``, you'll see verbose test result output (which normally isn't very useful). Alternatively, if you'd like to see test coverage, pass the ``--cov`` option -to ``py.test``: +to ``pytest``: .. code-block:: bash - $VENV/bin/py.test --cov -q + $VENV/bin/pytest --cov -q -Cookiecutters include configuration defaults for ``py.test`` and test coverage. +Cookiecutters include configuration defaults for ``pytest`` and test coverage. These configuration files are ``pytest.ini`` and ``.coveragerc``, located at the root of your package. Without these defaults, we would need to specify the path to the module on which we want to run tests and coverage. .. code-block:: bash - $VENV/bin/py.test --cov=myproject myproject/tests.py -q + $VENV/bin/pytest --cov=myproject myproject/tests.py -q -.. seealso:: See py.test's documentation for :ref:`pytest:usage` or invoke - ``py.test -h`` to see its full set of options. +.. seealso:: See pytest's documentation for :ref:`pytest:usage` or invoke + ``pytest -h`` to see its full set of options. .. index:: @@ -1042,7 +1042,7 @@ The ``tests.py`` module includes tests for your application. :linenos: This sample ``tests.py`` file has one unit test and one functional test defined -within it. These tests are executed when you run ``py.test -q``. You may add +within it. These tests are executed when you run ``pytest -q``. You may add more tests here as you build your application. You are not required to write tests to use :app:`Pyramid`. This file is simply provided for convenience and example. diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index ad4ba2186..8048ca62c 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -275,7 +275,7 @@ without needing to invoke the actual application configuration implied by its In the above example, we create a ``MyTest`` test case that inherits from :class:`unittest.TestCase`. If it's in our :app:`Pyramid` application, it will -be found when ``py.test`` is run. It has two test methods. +be found when ``pytest`` is run. It has two test methods. The first test method, ``test_view_fn_forbidden`` tests the ``view_fn`` when the authentication policy forbids the current user the ``edit`` permission. Its @@ -365,7 +365,7 @@ Functional tests test your literal application. In Pyramid, functional tests are typically written using the :term:`WebTest` package, which provides APIs for invoking HTTP(S) requests to your application. -We also like ``py.test`` and ``pytest-cov`` to provide simple testing and +We also like ``pytest`` and ``pytest-cov`` to provide simple testing and coverage reports. Regardless of which testing :term:`package` you use, be sure to add a -- cgit v1.2.3 From 1f307db52785634d6667fde8de0273d5e0612310 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 3 Oct 2018 20:13:34 -0500 Subject: remove deprecated set_request_property --- docs/narr/advconfig.rst | 1 - docs/narr/subrequest.rst | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 880e538f1..322741648 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -299,7 +299,6 @@ These are the methods of the configurator which provide conflict detection: :meth:`~pyramid.config.Configurator.add_request_method`, :meth:`~pyramid.config.Configurator.set_request_factory`, :meth:`~pyramid.config.Configurator.set_session_factory`, -:meth:`~pyramid.config.Configurator.set_request_property`, :meth:`~pyramid.config.Configurator.set_root_factory`, :meth:`~pyramid.config.Configurator.set_view_mapper`, :meth:`~pyramid.config.Configurator.set_authentication_policy`, diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 9094c7d83..03f372446 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -232,8 +232,7 @@ unconditionally does the following: callable) to the request object to which it is handed. - It sets request extensions (such as those added via - :meth:`~pyramid.config.Configurator.add_request_method` or - :meth:`~pyramid.config.Configurator.set_request_property`) on the subrequest + :meth:`~pyramid.config.Configurator.add_request_method`) on the subrequest object passed as ``request``. - It causes a :class:`~pyramid.events.NewRequest` event to be sent at the -- cgit v1.2.3 From 9c39f657e9edbb59ef83a375500596f500c70a44 Mon Sep 17 00:00:00 2001 From: Paul Cutler Date: Thu, 4 Oct 2018 11:02:14 -0500 Subject: Update Pyramid documentation pytest references with feedback Update the pull request to update all Pyramid documentation to replace instances of "py.test" with "pytest" to include missing backticks where needed. --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index a15138207..5efc07e09 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -286,7 +286,7 @@ path to the module on which we want to run tests and coverage. $VENV/bin/pytest --cov=myproject myproject/tests.py -q -.. seealso:: See pytest's documentation for :ref:`pytest:usage` or invoke +.. seealso:: See ``pytest``'s documentation for :ref:`pytest:usage` or invoke ``pytest -h`` to see its full set of options. -- cgit v1.2.3