Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add CSRF support thanks for Damon

git-svn-id: https://uliweb.googlecode.com/svn/trunk@1019 14287918-b64d-0410-abb6-a92efa0c2026
  • Loading branch information...
commit 591ced3fad0350c69e52c4259beea96ada7e60c8 1 parent c38f234
limodou authored
View
4 AUTHORS.md
@@ -3,4 +3,6 @@ Thanks a lot
Uliweb needs you to help, and blow are the people who help improving Uliweb very well.
-* damonchen [DOC]
+* damonchen(netutu AT gmail.com) [DOC][CODE]
+ * doc fix
+ * CSRF app origin version
View
40 uliweb/contrib/csrf/__init__.py
@@ -0,0 +1,40 @@
+import time
+import uuid
+from werkzeug.exceptions import Forbidden
+
+def csrf_token():
+ """
+ Get csrf token or create new one
+ """
+ from uliweb import request, settings
+
+ v = {}
+ token_name = settings.CSRF.cookie_token_name
+ if request.session.get(token_name):
+ v = request.session[token_name]
+ if time.time() >= v['created_time'] + v['expiry_time']:
+ v = {}
+ if not v:
+ token = request.cookies.get(token_name)
+ if not token:
+ token = uuid.uuid4().get_hex()
+
+ v = {'token':token, 'expiry_time':settings.CSRF.timeout, 'created_time':time.time()}
+
+ request.session[token_name] = v
+ return v['token']
+
+def check_csrf_token():
+ """
+ Check token
+ """
+ from uliweb import request, settings
+
+ token = (request.params.get(settings.CSRF.form_token_name, None) or
+ request.headers.get("X-Xsrftoken") or
+ request.headers.get("X-Csrftoken"))
+
+ if not token:
+ raise Forbidden("CSRF token missing.")
+ if csrf_token() != token:
+ raise Forbidden("CSRF token dismatched.")
View
9 uliweb/contrib/csrf/conf.py
@@ -0,0 +1,9 @@
+#! /usr/bin/env python
+#coding=utf-8
+
+from uliweb.form import *
+
+#class ManageForm(Form):
+# debug_log = BooleanField(label='Debug Log:', key='ORM/DEBUG_LOG')
+# auto_create = BooleanField(label='Auto Create Table:', key='ORM/AUTO_CREATE')
+# connection = StringField(label='Database Connection String:', required=True, key='ORM/CONNECTION')
View
4 uliweb/contrib/csrf/config.ini
@@ -0,0 +1,4 @@
+[DEPENDS]
+REQUIRED_APPS = [
+ 'uliweb.contrib.session',
+]
View
9 uliweb/contrib/csrf/info.ini
@@ -0,0 +1,9 @@
+[info]
+catalog = ''
+title = 'CSRF'
+description = 'see http://baike.baidu.com/view/1609487.htm'
+icon = ''
+author = 'DamonChen'
+version = '0.0.1a'
+homepage = 'http://www.cnblogs.com/ubunoon'
+date = '2012-9-5'
View
46 uliweb/contrib/csrf/middleware.py
@@ -0,0 +1,46 @@
+#! /usr/bin/env python
+#coding=utf-8
+
+import re
+
+from uliweb import Middleware, functions
+
+_POST_FORM_RE = re.compile(r'(<form\W[^>]*\bmethod\s*=\s*(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)
+
+_HTML_TYPES = ('text/html', 'application/xhtml+xml')
+
+class CSRFMiddleware(Middleware):
+ ORDER = 150
+
+ def __init__(self, application, settings):
+ super(CSRFMiddleware, self).__init__(application, settings)
+
+ def process_request(self, request):
+ # process each request
+ if self.settings.get_var('CSRF/enable', False):
+ if request.method in ('POST', 'DELETE') or (request.method == 'GET' and request.GET.get(self.settings.CSRF.form_token_name)):
+ functions.check_csrf_token()
+
+ def process_response(self, request, response):
+ if not self.settings.get_var('CSRF/enable', False):
+ return response
+
+ token = functions.csrf_token()
+
+ response.set_cookie(self.settings.CSRF.cookie_token_name, token, max_age=self.settings.CSRF.timeout)
+
+ if getattr(response, 'csrf_pass', False):
+ return response
+
+ if response.headers['Content-Type'].split(';')[0] in _HTML_TYPES:
+
+ def add_csrf_field(match):
+ """Returns the matched <form> tag plus the added <input> element"""
+
+ return (match.group() +
+ '\n<input type="hidden" name="%s" value="%s">' % (self.settings.CSRF.form_token_name, functions.csrf_token()))
+
+ # Modify any POST forms
+ response.data = _POST_FORM_RE.sub(add_csrf_field, response.data)
+
+ return response
View
12 uliweb/contrib/csrf/settings.ini
@@ -0,0 +1,12 @@
+[MIDDLEWARES]
+csrf = 'uliweb.contrib.csrf.middleware.CSRFMiddleware', 150
+
+[CSRF]
+enable = True
+timeout = 30*60 #seconds
+form_token_name = 'csrf_token'
+cookie_token_name = '_csrf_token'
+
+[FUNCTIONS]
+csrf_token = 'uliweb.contrib.csrf.csrf_token'
+check_csrf_token = 'uliweb.contrib.csrf.check_csrf_token'
View
1  uliweb/contrib/csrf/static/readme.txt
@@ -0,0 +1 @@
+This directory is used to store static files.
View
31 uliweb/contrib/csrf/templates/inc_jquery_csrf.html
@@ -0,0 +1,31 @@
+<script>
+// using jQuery
+function getCookie(name) {
+ var cookieValue = null;
+ if (document.cookie && document.cookie != '') {
+ var cookies = document.cookie.split(';');
+ for (var i = 0; i < cookies.length; i++) {
+ var cookie = jQuery.trim(cookies[i]);
+ // Does this cookie string begin with the name we want?
+ if (cookie.substring(0, name.length + 1) == (name + '=')) {
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+ break;
+ }
+ }
+ }
+ return cookieValue;
+}
+
+function csrfSafeMethod(method) {
+ // these HTTP methods do not require CSRF protection
+ return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
+}
+$.ajaxSetup({
+ crossDomain: false, // obviates need for sameOrigin test
+ beforeSend: function(xhr, settings) {
+ if (!csrfSafeMethod(settings.type)) {
+ xhr.setRequestHeader("X-CSRFToken", getCookie('{{=settings.CSRF.cookie_token_name}}'));
+ }
+ }
+});
+</script>
View
1  uliweb/contrib/csrf/templates/readme.txt
@@ -0,0 +1 @@
+This directory is used to store template files.
Please sign in to comment.
Something went wrong with that request. Please try again.