aboutsummaryrefslogtreecommitdiffstats
path: root/mediagoblin/middleware/csrf.py
diff options
context:
space:
mode:
authorChristopher Allan Webber <cwebber@dustycloud.org>2011-11-25 12:13:56 -0600
committerChristopher Allan Webber <cwebber@dustycloud.org>2011-11-25 12:13:56 -0600
commitce5ae8da19707019cd62d42533e591d71071f4fe (patch)
tree19a14eb016865447292f4f5f298d6f3d337596d6 /mediagoblin/middleware/csrf.py
parent4da6efb45956321d831339da0fcdbbb6553c6846 (diff)
downloadmediagoblin-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.py132
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()