]> asedeno.scripts.mit.edu Git - bluechips.git/commitdiff
added XSRF protection to all forms and associated tests
authorScott Torborg <scott@crookedmedia.com>
Sun, 8 Nov 2009 23:54:09 +0000 (15:54 -0800)
committerScott Torborg <scott@crookedmedia.com>
Sun, 8 Nov 2009 23:54:09 +0000 (15:54 -0800)
bluechips/controllers/spend.py
bluechips/controllers/transfer.py
bluechips/controllers/user.py
bluechips/lib/helpers.py
bluechips/templates/spend/index.mako
bluechips/templates/transfer/index.mako
bluechips/templates/user/index.mako
bluechips/tests/functional/test_spend.py
bluechips/tests/functional/test_transfer.py
bluechips/tests/functional/test_user.py

index aceb6ade6a839519217703bfe5d8c647afcd0a05..098ac270ceaad3ca0684a6973d7353f1a3097fda 100644 (file)
@@ -9,8 +9,8 @@ from decimal import Decimal, InvalidOperation
 from bluechips.lib.base import *
 
 from pylons import request, app_globals as g
-from pylons.decorators.rest import dispatch_on
 from pylons.decorators import validate
+from pylons.decorators.secure import authenticate_form
 from pylons.controllers.util import abort
 
 from formencode import validators, Schema
@@ -91,6 +91,7 @@ class SpendController(BaseController):
         return render('/spend/index.mako')
 
     @redirect_on_get('edit')
+    @authenticate_form
     @validate(schema=ExpenditureSchema(), form='edit', variable_decode=True)
     def update(self, id=None):
         # Either create a new object, or, if we're editing, get the
index 50948456fad832da5bd81035aee1ea08a6d15d8c..ed0601845fc58b9db6f8ad67bfd1daf1e10d0702 100644 (file)
@@ -10,6 +10,7 @@ from bluechips.lib.base import *
 
 from pylons import request, app_globals as g
 from pylons.decorators import validate
+from pylons.decorators.secure import authenticate_form
 from pylons.controllers.util import abort
 
 from formencode import Schema, validators
@@ -48,6 +49,7 @@ class TransferController(BaseController):
         return render('/transfer/index.mako')
     
     @redirect_on_get('edit')
+    @authenticate_form
     @validate(schema=TransferSchema(), form='edit')
     def update(self, id=None):
         if id is None:
index df8253e83811e570ccb7eef23d7da31feb16b339..b432126a15d587acb64f0fcfa4d88e8f4c975e46 100644 (file)
@@ -11,6 +11,7 @@ from sqlalchemy import orm
 
 from pylons import request
 from pylons.decorators import validate
+from pylons.decorators.secure import authenticate_form
 
 from formencode import validators, Schema
 
@@ -28,6 +29,7 @@ class UserController(BaseController):
         c.title = 'User Settings'
         return render('/user/index.mako')
 
+    @authenticate_form
     @validate(schema=EmailSchema(), form='index')
     def update(self):
         new_email = self.form_result['new_email']
index 1a05266637923bc141407f70ee28c7ff880d33cd..8da5a575b21d8adf6b6f619147ea416b0f5729c3 100644 (file)
@@ -6,6 +6,7 @@ available to Controllers. This module is available to both as 'h'.
 from routes import url_for, redirect_to
 from webhelpers.html import escape, literal, url_escape
 from webhelpers.html.tags import *
+from webhelpers.html.secure_form import *
 
 from webhelpers.pylonslib import Flash as _Flash
 
index 25f1db2c432683a70f76ccf02136ded4fb043174..ff388a3eecace604ab6cb86bd8cb13efb9245091 100644 (file)
@@ -5,6 +5,7 @@
 %>
 
 <form action="${h.url_for(controller='spend', action='update', id=c.expenditure.id)}" method="post">
+  ${h.auth_token_hidden_field()}
   <table class="form">
     <tr>
       <th><label for="spender_id">Spender</label></th>
index 736c339c34a81fb6e4dc2ba272315842d2e3fb37..7c3daa925f2d2a0fd1b28354ccd58344b43e48e3 100644 (file)
@@ -1,6 +1,7 @@
 <%inherit file="/base.mako"/>
 
 <form action="${h.url_for(controller='transfer', action='update', id=c.transfer.id)}" method="post">
+  ${h.auth_token_hidden_field()}
   <table class="form">
     <tr>
       <th><label for="debtor_id">From</label></th>
index c2932525a3bb42aa14f4c77bce41d24e3eff4a2d..af8d3a646df90daff171a620bfd3d5b3094eb355 100644 (file)
@@ -4,6 +4,7 @@
 
 <p>Enter an email address below if you wish to be notified of any updates to transactions involving you. Leave blank to not receive notifications.</p>
 <form action="${h.url_for(controller='user', action='update')}" method="post">
+  ${h.auth_token_hidden_field()}
   <table class="form">
     <tr>
       <th><label for="new_email">Email</label></th>
index 801c5808b88588f952779167fa632dddb61daf02..125ac0649b579f8b0cf7fd78f2c3c4fbe6c1b601 100644 (file)
@@ -1,6 +1,8 @@
 from datetime import date
 from formencode import Invalid
 
+from webhelpers.html.secure_form import token_key
+
 from bluechips.tests import *
 
 from bluechips import model
@@ -111,11 +113,21 @@ class TestSpendController(TestController):
                                         id=124234), status=404)
 
     def test_update_nonexistent(self):
-        response = self.app.post(url_for(controller='spend',
-                                         action='update',
-                                         id=14234), 
-                                 params=self.sample_post,
-                                 status=404)
+        response = self.app.get(url_for(controller='spend',
+                                        action='edit'))
+        params = self.sample_post.copy()
+        params[token_key] = response.form[token_key].value
+        self.app.post(url_for(controller='spend',
+                              action='update',
+                              id=14234), 
+                      params=params,
+                      status=404)
+
+    def test_xsrf_protection(self):
+        self.app.post(url_for(controller='spend',
+                              action='update'),
+                      params=self.sample_post,
+                      status=403)
 
     def test_all_zero_shares_fails(self):
         params = self.sample_post.copy()
index 9e01e6a455725f8d82fdb6dd375dff4a165aa858..69eba4668b27fbe4579d3b64d00fb7b28d24b322 100644 (file)
@@ -1,7 +1,9 @@
 from datetime import date
 from decimal import Decimal
-from bluechips.tests import *
 
+from webhelpers.html.secure_form import token_key
+
+from bluechips.tests import *
 from bluechips import model
 from bluechips.model import meta
 
@@ -76,11 +78,22 @@ class TestTransferController(TestController):
                                         id=21424), status=404)
 
     def test_update_nonexistent(self):
-        response = self.app.post(url_for(controller='transfer',
-                                         action='update',
-                                         id=21424),
-                                 params=self.sample_params,
-                                 status=404)
+        response = self.app.get(url_for(controller='transfer',
+                                        action='edit'))
+        params = self.sample_params.copy()
+        params[token_key] = response.form[token_key].value
+        self.app.post(url_for(controller='transfer',
+                              action='update',
+                              id=21424),
+                      params=params,
+                      status=404)
+
+    def test_xsrf_protection(self):
+        self.app.post(url_for(controller='transfer',
+                              action='update'),
+                      params=self.sample_params,
+                      status=403)
+
 
     def test_update_get_redirects(self):
         response = self.app.get(url_for(controller='transfer',
index b5c91364ec6c4c36169dd426a2a0439760788663..c27983b97457ee6077f2788a63b9593a70439b47 100644 (file)
@@ -30,4 +30,8 @@ class TestUserController(TestController):
                 filter_by(username=unicode(config['fake_username'])).one()
         assert user.email == None
 
-
+    def test_xsrf_protection(self):
+        self.app.post(url_for(controller='user',
+                              action='update'),
+                      {'new_email': 'malicious@example.com'},
+                      status=403)