diff options
author | Christopher Allan Webber <cwebber@dustycloud.org> | 2011-11-25 12:13:56 -0600 |
---|---|---|
committer | Christopher Allan Webber <cwebber@dustycloud.org> | 2011-11-25 12:13:56 -0600 |
commit | ce5ae8da19707019cd62d42533e591d71071f4fe (patch) | |
tree | 19a14eb016865447292f4f5f298d6f3d337596d6 /mediagoblin/middleware/csrf.py | |
parent | 4da6efb45956321d831339da0fcdbbb6553c6846 (diff) | |
download | mediagoblin-ce5ae8da19707019cd62d42533e591d71071f4fe.tar.lz mediagoblin-ce5ae8da19707019cd62d42533e591d71071f4fe.tar.xz mediagoblin-ce5ae8da19707019cd62d42533e591d71071f4fe.zip |
Rename MediaGoblin middleware to meddleware to avoid confusion w/ wsgi middleware
hehehehehe, "meddleware"
Diffstat (limited to 'mediagoblin/middleware/csrf.py')
-rw-r--r-- | mediagoblin/middleware/csrf.py | 132 |
1 files changed, 0 insertions, 132 deletions
diff --git a/mediagoblin/middleware/csrf.py b/mediagoblin/middleware/csrf.py deleted file mode 100644 index 8275c18e..00000000 --- a/mediagoblin/middleware/csrf.py +++ /dev/null @@ -1,132 +0,0 @@ -# GNU MediaGoblin -- federated, autonomous media hosting -# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -import hashlib -import random - -from webob.exc import HTTPForbidden -from wtforms import Form, HiddenField, validators - -from mediagoblin import mg_globals - -# Use the system (hardware-based) random number generator if it exists. -# -- this optimization is lifted from Django -if hasattr(random, 'SystemRandom'): - getrandbits = random.SystemRandom().getrandbits -else: - getrandbits = random.getrandbits - - -class CsrfForm(Form): - """Simple form to handle rendering a CSRF token and confirming it - is included in the POST.""" - - csrf_token = HiddenField("", - [validators.Required()]) - - -def render_csrf_form_token(request): - """Render the CSRF token in a format suitable for inclusion in a - form.""" - - form = CsrfForm(csrf_token=request.environ['CSRF_TOKEN']) - - return form.csrf_token - - -class CsrfMiddleware(object): - """CSRF Protection Middleware - - Adds a CSRF Cookie to responses and verifies that it is present - and matches the form token for non-safe requests. - """ - - CSRF_KEYLEN = 64 - SAFE_HTTP_METHODS = ("GET", "HEAD", "OPTIONS", "TRACE") - - def __init__(self, mg_app): - self.app = mg_app - - def process_request(self, request): - """For non-safe requests, confirm that the tokens are present - and match. - """ - - # get the token from the cookie - try: - request.environ['CSRF_TOKEN'] = \ - request.cookies[mg_globals.app_config['csrf_cookie_name']] - - except KeyError, e: - # if it doesn't exist, make a new one - request.environ['CSRF_TOKEN'] = self._make_token(request) - - # if this is a non-"safe" request (ie, one that could have - # side effects), confirm that the CSRF tokens are present and - # valid - if request.method not in self.SAFE_HTTP_METHODS \ - and ('gmg.verify_csrf' in request.environ or - 'paste.testing' not in request.environ): - - return self.verify_tokens(request) - - def process_response(self, request, response): - """Add the CSRF cookie to the response if needed and set Vary - headers. - """ - - # set the CSRF cookie - response.set_cookie( - mg_globals.app_config['csrf_cookie_name'], - request.environ['CSRF_TOKEN'], - path=request.environ['SCRIPT_NAME'], - domain=mg_globals.app_config.get('csrf_cookie_domain'), - secure=(request.scheme.lower() == 'https'), - httponly=True) - - # update the Vary header - response.vary = (getattr(response, 'vary', None) or []) + ['Cookie'] - - def _make_token(self, request): - """Generate a new token to use for CSRF protection.""" - - return "%s" % (getrandbits(self.CSRF_KEYLEN),) - - def verify_tokens(self, request): - """Verify that the CSRF Cookie exists and that it matches the - form value.""" - - # confirm the cookie token was presented - cookie_token = request.cookies.get( - mg_globals.app_config['csrf_cookie_name'], - None) - - if cookie_token is None: - # the CSRF cookie must be present in the request - return HTTPForbidden() - - # get the form token and confirm it matches - form = CsrfForm(request.POST) - if form.validate(): - form_token = form.csrf_token.data - - if form_token == cookie_token: - # all's well that ends well - return - - # either the tokens didn't match or the form token wasn't - # present; either way, the request is denied - return HTTPForbidden() |