comparison test/test_actions.py @ 4880:ca692423e401

Different approach to fix XSS in issue2550817 Encapsulate the error/ok message append method as add_ok_message and add_error_message. The new approach escapes the messages when appending -- at a point in the code where we still know where the message comes from. Escaping is the default but can bei turned off. This also fixes issue2550836 where certain messages may contain links. Another advantage of the new fix is that users don't need to change installed trackers and are secure by default.
author Ralf Schlatterbeck <rsc@runtux.com>
date Mon, 31 Mar 2014 18:19:23 +0200
parents 9cc6d463cfbe
children b562df8a5056
comparison
equal deleted inserted replaced
4879:302c967d710c 4880:ca692423e401
2 from cgi import FieldStorage, MiniFieldStorage 2 from cgi import FieldStorage, MiniFieldStorage
3 3
4 from roundup import hyperdb 4 from roundup import hyperdb
5 from roundup.date import Date, Interval 5 from roundup.date import Date, Interval
6 from roundup.cgi.actions import * 6 from roundup.cgi.actions import *
7 from roundup.cgi.client import add_message
7 from roundup.cgi.exceptions import Redirect, Unauthorised, SeriousError 8 from roundup.cgi.exceptions import Redirect, Unauthorised, SeriousError
8 9
9 from mocknull import MockNull 10 from mocknull import MockNull
10 11
11 def true(*args, **kwargs): 12 def true(*args, **kwargs):
13 14
14 class ActionTestCase(unittest.TestCase): 15 class ActionTestCase(unittest.TestCase):
15 def setUp(self): 16 def setUp(self):
16 self.form = FieldStorage() 17 self.form = FieldStorage()
17 self.client = MockNull() 18 self.client = MockNull()
19 self.client._ok_message = []
20 self.client._error_message = []
21 self.client.add_error_message = lambda x : add_message(
22 self.client._error_message, x)
23 self.client.add_ok_message = lambda x : add_message(
24 self.client._ok_message, x)
18 self.client.form = self.form 25 self.client.form = self.form
19 class TemplatingUtils: 26 class TemplatingUtils:
20 pass 27 pass
21 self.client.instance.interfaces.TemplatingUtils = TemplatingUtils 28 self.client.instance.interfaces.TemplatingUtils = TemplatingUtils
22 29
58 'No type specified') 65 'No type specified')
59 66
60 class RetireActionTestCase(ActionTestCase): 67 class RetireActionTestCase(ActionTestCase):
61 def testRetireAction(self): 68 def testRetireAction(self):
62 self.client.db.security.hasPermission = true 69 self.client.db.security.hasPermission = true
63 self.client.ok_message = [] 70 self.client._ok_message = []
64 RetireAction(self.client).handle() 71 RetireAction(self.client).handle()
65 self.assert_(len(self.client.ok_message) == 1) 72 self.assert_(len(self.client._ok_message) == 1)
66 73
67 def testNoPermission(self): 74 def testNoPermission(self):
68 self.assertRaises(Unauthorised, RetireAction(self.client).execute) 75 self.assertRaises(Unauthorised, RetireAction(self.client).execute)
69 76
70 def testDontRetireAdminOrAnonymous(self): 77 def testDontRetireAdminOrAnonymous(self):
177 self.failIf(self.action.detectCollision(None, self.now)) 184 self.failIf(self.action.detectCollision(None, self.now))
178 185
179 class LoginTestCase(ActionTestCase): 186 class LoginTestCase(ActionTestCase):
180 def setUp(self): 187 def setUp(self):
181 ActionTestCase.setUp(self) 188 ActionTestCase.setUp(self)
182 self.client.error_message = [] 189 self.client._error_message = []
183 190
184 # set the db password to 'right' 191 # set the db password to 'right'
185 self.client.db.user.get = lambda a,b: 'right' 192 self.client.db.user.get = lambda a,b: 'right'
186 193
187 # unless explicitly overridden, we should never get here 194 # unless explicitly overridden, we should never get here
194 if password is not None: 201 if password is not None:
195 self.form.value.append( 202 self.form.value.append(
196 MiniFieldStorage('__login_password', password)) 203 MiniFieldStorage('__login_password', password))
197 204
198 LoginAction(self.client).handle() 205 LoginAction(self.client).handle()
199 self.assertEqual(self.client.error_message, messages) 206 self.assertEqual(self.client._error_message, messages)
200 207
201 def testNoUsername(self): 208 def testNoUsername(self):
202 self.assertLoginLeavesMessages(['Username required']) 209 self.assertLoginLeavesMessages(['Username required'])
203 210
204 def testInvalidUsername(self): 211 def testInvalidUsername(self):

Roundup Issue Tracker: http://roundup-tracker.org/