[PATCH] middleware: use secure cookies over secure connections
Mads Kiilerich
mads at kiilerich.com
Fri Mar 6 10:17:36 EST 2015
On 03/04/2015 11:58 PM, Andrew Shadura wrote:
> # HG changeset patch
> # User Andrew Shadura <andrew at shadura.me>
> # Date 1425509877 -3600
> # Wed Mar 04 23:57:57 2015 +0100
> # Node ID 6e0cecf00cdad2d108caca97c4cd9dece0333d73
> # Parent 599fba9967a4981e8c401c39521a52635dd93380
> middleware: use secure cookies over secure connections
>
> Use our own wrapper around Beaker's SessionMiddleware class to
> give secure cookies over HTTPS connections.
It would also be nice to have a clear statement of what problem this is
solving. There was no way to flag cookies as "secure" when using https?
In which scenarios would that be a problem ... and how big?
I assume it would be better to use plain Beaker for this ... but I
assume you have tried and researched and concluded that this was the
best way to do it? Please you share your findings - perhaps as a comment
in sessionmiddleware.py or in the commit message. Is it a bug or
not-yet-implemented feature or philosophical disagreement?
> diff --git a/kallithea/config/middleware.py b/kallithea/config/middleware.py
> --- a/kallithea/config/middleware.py
> +++ b/kallithea/config/middleware.py
> @@ -15,7 +15,6 @@
> Pylons middleware initialization
> """
>
> -from beaker.middleware import SessionMiddleware
> from routes.middleware import RoutesMiddleware
> from paste.cascade import Cascade
> from paste.registry import RegistryManager
> @@ -29,6 +28,7 @@ from pylons.wsgiapp import PylonsApp
> from kallithea.lib.middleware.simplehg import SimpleHg
> from kallithea.lib.middleware.simplegit import SimpleGit
> from kallithea.lib.middleware.https_fixup import HttpsFixup
> +from kallithea.lib.middleware.sessionmiddleware import SessionMiddleware
> from kallithea.config.environment import load_environment
> from kallithea.lib.middleware.wrapper import RequestWrapper
>
> diff --git a/kallithea/lib/middleware/sessionmiddleware.py b/kallithea/lib/middleware/sessionmiddleware.py
> new file mode 100644
> --- /dev/null
> +++ b/kallithea/lib/middleware/sessionmiddleware.py
> @@ -0,0 +1,78 @@
> +# -*- coding: utf-8 -*-
> +# This program is free software: you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation, either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +"""
> +kallithea.lib.middleware.sessionmiddleware
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +session management middleware
> +
> +This file overrides Beaker's built-in SessionMiddleware
> +class to automagically use secure cookies over HTTPS.
> +
> +Original Beaker SessionMiddleware class written by Ben Bangert
> +
> +:created_on: March 04, 2015
> +:author: andrewsh
> +:copyright: (c) 2015 Andrew Shadura
> +:license: GPLv3, see LICENSE.md for more details.
> +"""
Unless it already has been fixed / contributed upstream, the license of
this could perhaps be made compatible with upstream so they can take it
back?
> +from beaker.session import SessionObject
> +from beaker.middleware import SessionMiddleware as BeakerSessionMiddleware
> +
> +class SessionMiddleware(BeakerSessionMiddleware):
> + def __init__(self, wrap_app, config=None, environ_key='beaker.session',
> + **kwargs):
> + """
> + Initialise the session middleware
> +
> + Call Beaker's original constructor to set the options, then
> + unset secure option as we're handling that on our own and don't
> + want Beaker to interfere.
> + """
> + super(SessionMiddleware, self).__init__(wrap_app, config,
> + environ_key, **kwargs)
> + self.options["secure"] = False
> + # self.options["httponly"] = True
I guess this either should be removed or have a comment to explain what
the purpose is and when it can be useful?
> +
> + def __call__(self, environ, start_response):
> + """
> + This function's implementation is taken directly from Beaker,
> + with HTTPS detection added. When accessed over HTTPS, force
> + setting cookie's secure flag.
> + """
> + session = SessionObject(environ, **self.options)
> + if environ.get('paste.registry'):
> + if environ['paste.registry'].reglist:
> + environ['paste.registry'].register(self.session, session)
> + environ[self.environ_key] = session
> + environ['beaker.get_session'] = self._get_session
> +
> + if 'paste.testing_variables' in environ and 'webtest_varname' in self.options:
> + environ['paste.testing_variables'][self.options['webtest_varname']] = session
> +
> + is_ssl = environ['wsgi.url_scheme'] == 'https'
> +
> + def session_start_response(status, headers, exc_info=None):
> + if session.accessed():
> + session.persist()
> + if session.__dict__['_headers']['set_cookie']:
> + cookie = session.__dict__['_headers']['cookie_out']
> +
> + if is_ssl:
> + cookie += "; secure"
> + if cookie:
> + headers.append(('Set-cookie', cookie))
> + return start_response(status, headers, exc_info)
> + return self.wrap_app(environ, session_start_response)
> _______________________________________________
> kallithea-general mailing list
> kallithea-general at sfconservancy.org
> http://lists.sfconservancy.org/mailman/listinfo/kallithea-general
More information about the kallithea-general
mailing list