##// END OF EJS Templates
security: apply CSRF check to all non-GET requests...
Søren Løvborg -
r5471:a041321d default
parent child Browse files
Show More
@@ -760,8 +760,13 b' class LoginRequired(object):'
760 log.warning('API access to %s is not allowed', loc)
760 log.warning('API access to %s is not allowed', loc)
761 return abort(403)
761 return abort(403)
762
762
763 # CSRF protection - POSTs with session auth must contain correct token
763 # CSRF protection: Whenever a request has ambient authority (whether
764 if request.POST and user.is_authenticated:
764 # through a session cookie or its origin IP address), it must include
765 # the correct token, unless the HTTP method is GET or HEAD (and thus
766 # guaranteed to be side effect free.
767 # Note that the 'is_authenticated' flag is True for anonymous users too,
768 # but not when the user is authenticated by API key.
769 if user.is_authenticated and request.method not in ['GET', 'HEAD']:
765 token = request.POST.get(secure_form.token_key)
770 token = request.POST.get(secure_form.token_key)
766 if not token or token != secure_form.authentication_token():
771 if not token or token != secure_form.authentication_token():
767 log.error('CSRF check failed')
772 log.error('CSRF check failed')
@@ -16,7 +16,8 b' class TestDefaultsController(TestControl'
16 response = self.app.get(url('formatted_defaults', format='xml'))
16 response = self.app.get(url('formatted_defaults', format='xml'))
17
17
18 def test_create(self):
18 def test_create(self):
19 response = self.app.post(url('defaults'))
19 response = self.app.post(url('defaults'),
20 {'_authentication_token': self.authentication_token()})
20
21
21 def test_new(self):
22 def test_new(self):
22 response = self.app.get(url('new_default'))
23 response = self.app.get(url('new_default'))
@@ -62,7 +63,8 b' class TestDefaultsController(TestControl'
62 response = self.app.post(url('default', id=1), params=dict(_method='put', _authentication_token=self.authentication_token()))
63 response = self.app.post(url('default', id=1), params=dict(_method='put', _authentication_token=self.authentication_token()))
63
64
64 def test_delete(self):
65 def test_delete(self):
65 response = self.app.delete(url('default', id=1))
66 # Not possible due to CSRF protection.
67 response = self.app.delete(url('default', id=1), status=403)
66
68
67 def test_delete_browser_fakeout(self):
69 def test_delete_browser_fakeout(self):
68 response = self.app.post(url('default', id=1), params=dict(_method='delete', _authentication_token=self.authentication_token()))
70 response = self.app.post(url('default', id=1), params=dict(_method='delete', _authentication_token=self.authentication_token()))
@@ -136,19 +136,20 b' class TestGistsController(TestController'
136 def test_delete(self):
136 def test_delete(self):
137 self.log_user()
137 self.log_user()
138 gist = _create_gist('delete-me')
138 gist = _create_gist('delete-me')
139 response = self.app.delete(url('gist', gist_id=gist.gist_id))
139 response = self.app.post(url('gist', gist_id=gist.gist_id),
140 self.checkSessionFlash(response, 'Deleted gist %s' % gist.gist_id)
140 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
141
141
142 def test_delete_normal_user_his_gist(self):
142 def test_delete_normal_user_his_gist(self):
143 self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
143 self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
144 gist = _create_gist('delete-me', owner=TEST_USER_REGULAR_LOGIN)
144 gist = _create_gist('delete-me', owner=TEST_USER_REGULAR_LOGIN)
145 response = self.app.delete(url('gist', gist_id=gist.gist_id))
145 response = self.app.post(url('gist', gist_id=gist.gist_id),
146 self.checkSessionFlash(response, 'Deleted gist %s' % gist.gist_id)
146 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
147
147
148 def test_delete_normal_user_not_his_own_gist(self):
148 def test_delete_normal_user_not_his_own_gist(self):
149 self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
149 self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
150 gist = _create_gist('delete-me')
150 gist = _create_gist('delete-me')
151 response = self.app.delete(url('gist', gist_id=gist.gist_id), status=403)
151 response = self.app.post(url('gist', gist_id=gist.gist_id), status=403,
152 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
152
153
153 def test_show(self):
154 def test_show(self):
154 gist = _create_gist('gist-show-me')
155 gist = _create_gist('gist-show-me')
@@ -56,9 +56,9 b' class TestNotificationsController(TestCo'
56 self.assertEqual(get_notif(u2.notifications), [notification])
56 self.assertEqual(get_notif(u2.notifications), [notification])
57 cur_usr_id = cur_user.user_id
57 cur_usr_id = cur_user.user_id
58
58
59 response = self.app.delete(url('notification',
59 response = self.app.post(
60 notification_id=
60 url('notification', notification_id=notification.notification_id),
61 notification.notification_id))
61 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
62 self.assertEqual(response.body, 'ok')
62 self.assertEqual(response.body, 'ok')
63
63
64 cur_user = User.get(cur_usr_id)
64 cur_user = User.get(cur_usr_id)
@@ -398,7 +398,8 b' class _BaseTest(object):'
398 except vcs.exceptions.VCSError:
398 except vcs.exceptions.VCSError:
399 self.fail('no repo %s in filesystem' % repo_name)
399 self.fail('no repo %s in filesystem' % repo_name)
400
400
401 response = self.app.delete(url('delete_repo', repo_name=repo_name))
401 response = self.app.post(url('delete_repo', repo_name=repo_name),
402 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
402
403
403 self.checkSessionFlash(response, 'Deleted repository %s' % (repo_name))
404 self.checkSessionFlash(response, 'Deleted repository %s' % (repo_name))
404
405
@@ -450,7 +451,8 b' class _BaseTest(object):'
450 except vcs.exceptions.VCSError:
451 except vcs.exceptions.VCSError:
451 self.fail('no repo %s in filesystem' % repo_name)
452 self.fail('no repo %s in filesystem' % repo_name)
452
453
453 response = self.app.delete(url('delete_repo', repo_name=repo_name))
454 response = self.app.post(url('delete_repo', repo_name=repo_name),
455 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
454 self.checkSessionFlash(response, 'Deleted repository %s' % (repo_name_unicode))
456 self.checkSessionFlash(response, 'Deleted repository %s' % (repo_name_unicode))
455 response.follow()
457 response.follow()
456
458
@@ -32,7 +32,7 b' class TestAdminUsersGroupsController(Tes'
32 response = self.app.get(url('new_users_group'))
32 response = self.app.get(url('new_users_group'))
33
33
34 def test_update(self):
34 def test_update(self):
35 response = self.app.put(url('users_group', id=1))
35 response = self.app.put(url('users_group', id=1), status=403)
36
36
37 def test_update_browser_fakeout(self):
37 def test_update_browser_fakeout(self):
38 response = self.app.post(url('users_group', id=1),
38 response = self.app.post(url('users_group', id=1),
@@ -54,7 +54,8 b' class TestAdminUsersGroupsController(Tes'
54 gr = Session().query(UserGroup)\
54 gr = Session().query(UserGroup)\
55 .filter(UserGroup.users_group_name == users_group_name).one()
55 .filter(UserGroup.users_group_name == users_group_name).one()
56
56
57 response = self.app.delete(url('users_group', id=gr.users_group_id))
57 response = self.app.post(url('users_group', id=gr.users_group_id),
58 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
58
59
59 gr = Session().query(UserGroup)\
60 gr = Session().query(UserGroup)\
60 .filter(UserGroup.users_group_name == users_group_name).scalar()
61 .filter(UserGroup.users_group_name == users_group_name).scalar()
@@ -97,7 +98,8 b' class TestAdminUsersGroupsController(Tes'
97
98
98 ## DISABLE REPO CREATE ON A GROUP
99 ## DISABLE REPO CREATE ON A GROUP
99 response = self.app.put(
100 response = self.app.put(
100 url('edit_user_group_default_perms', id=ug.users_group_id), {})
101 url('edit_user_group_default_perms', id=ug.users_group_id),
102 params={'_authentication_token': self.authentication_token()})
101
103
102 response.follow()
104 response.follow()
103 ug = UserGroup.get_by_group_name(users_group_name)
105 ug = UserGroup.get_by_group_name(users_group_name)
@@ -119,7 +121,8 b' class TestAdminUsersGroupsController(Tes'
119 # DELETE !
121 # DELETE !
120 ug = UserGroup.get_by_group_name(users_group_name)
122 ug = UserGroup.get_by_group_name(users_group_name)
121 ugid = ug.users_group_id
123 ugid = ug.users_group_id
122 response = self.app.delete(url('users_group', id=ug.users_group_id))
124 response = self.app.post(url('users_group', id=ug.users_group_id),
125 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
123 response = response.follow()
126 response = response.follow()
124 gr = Session().query(UserGroup)\
127 gr = Session().query(UserGroup)\
125 .filter(UserGroup.users_group_name == users_group_name).scalar()
128 .filter(UserGroup.users_group_name == users_group_name).scalar()
@@ -167,8 +170,8 b' class TestAdminUsersGroupsController(Tes'
167 [ug.users_group_id, p3.permission_id]]))
170 [ug.users_group_id, p3.permission_id]]))
168
171
169 ## DISABLE REPO CREATE ON A GROUP
172 ## DISABLE REPO CREATE ON A GROUP
170 response = self.app.put(
173 response = self.app.put(url('edit_user_group_default_perms', id=ug.users_group_id),
171 url('edit_user_group_default_perms', id=ug.users_group_id), {})
174 params={'_authentication_token': self.authentication_token()})
172
175
173 response.follow()
176 response.follow()
174 ug = UserGroup.get_by_group_name(users_group_name)
177 ug = UserGroup.get_by_group_name(users_group_name)
@@ -189,7 +192,8 b' class TestAdminUsersGroupsController(Tes'
189 # DELETE !
192 # DELETE !
190 ug = UserGroup.get_by_group_name(users_group_name)
193 ug = UserGroup.get_by_group_name(users_group_name)
191 ugid = ug.users_group_id
194 ugid = ug.users_group_id
192 response = self.app.delete(url('users_group', id=ug.users_group_id))
195 response = self.app.post(url('users_group', id=ug.users_group_id),
196 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
193 response = response.follow()
197 response = response.follow()
194 gr = Session().query(UserGroup)\
198 gr = Session().query(UserGroup)\
195 .filter(UserGroup.users_group_name ==
199 .filter(UserGroup.users_group_name ==
@@ -167,7 +167,8 b' class TestAdminUsersController(TestContr'
167
167
168 new_user = Session().query(User)\
168 new_user = Session().query(User)\
169 .filter(User.username == username).one()
169 .filter(User.username == username).one()
170 response = self.app.delete(url('user', id=new_user.user_id))
170 response = self.app.post(url('user', id=new_user.user_id),
171 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
171
172
172 self.checkSessionFlash(response, 'Successfully deleted user')
173 self.checkSessionFlash(response, 'Successfully deleted user')
173
174
@@ -181,16 +182,19 b' class TestAdminUsersController(TestContr'
181
182
182 new_user = Session().query(User)\
183 new_user = Session().query(User)\
183 .filter(User.username == username).one()
184 .filter(User.username == username).one()
184 response = self.app.delete(url('user', id=new_user.user_id))
185 response = self.app.post(url('user', id=new_user.user_id),
186 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
185 self.checkSessionFlash(response, 'User "%s" still '
187 self.checkSessionFlash(response, 'User "%s" still '
186 'owns 1 repositories and cannot be removed. '
188 'owns 1 repositories and cannot be removed. '
187 'Switch owners or remove those repositories: '
189 'Switch owners or remove those repositories: '
188 '%s' % (username, reponame))
190 '%s' % (username, reponame))
189
191
190 response = self.app.delete(url('delete_repo', repo_name=reponame))
192 response = self.app.post(url('delete_repo', repo_name=reponame),
193 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
191 self.checkSessionFlash(response, 'Deleted repository %s' % reponame)
194 self.checkSessionFlash(response, 'Deleted repository %s' % reponame)
192
195
193 response = self.app.delete(url('user', id=new_user.user_id))
196 response = self.app.post(url('user', id=new_user.user_id),
197 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
194 self.checkSessionFlash(response, 'Successfully deleted user')
198 self.checkSessionFlash(response, 'Successfully deleted user')
195
199
196 def test_delete_repo_group_err(self):
200 def test_delete_repo_group_err(self):
@@ -203,7 +207,8 b' class TestAdminUsersController(TestContr'
203
207
204 new_user = Session().query(User)\
208 new_user = Session().query(User)\
205 .filter(User.username == username).one()
209 .filter(User.username == username).one()
206 response = self.app.delete(url('user', id=new_user.user_id))
210 response = self.app.post(url('user', id=new_user.user_id),
211 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
207 self.checkSessionFlash(response, 'User "%s" still '
212 self.checkSessionFlash(response, 'User "%s" still '
208 'owns 1 repository groups and cannot be removed. '
213 'owns 1 repository groups and cannot be removed. '
209 'Switch owners or remove those repository groups: '
214 'Switch owners or remove those repository groups: '
@@ -213,10 +218,12 b' class TestAdminUsersController(TestContr'
213 # rg = RepoGroup.get_by_group_name(group_name=groupname)
218 # rg = RepoGroup.get_by_group_name(group_name=groupname)
214 # response = self.app.get(url('repos_groups', id=rg.group_id))
219 # response = self.app.get(url('repos_groups', id=rg.group_id))
215
220
216 response = self.app.delete(url('delete_repo_group', group_name=groupname))
221 response = self.app.post(url('delete_repo_group', group_name=groupname),
222 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
217 self.checkSessionFlash(response, 'Removed repository group %s' % groupname)
223 self.checkSessionFlash(response, 'Removed repository group %s' % groupname)
218
224
219 response = self.app.delete(url('user', id=new_user.user_id))
225 response = self.app.post(url('user', id=new_user.user_id),
226 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
220 self.checkSessionFlash(response, 'Successfully deleted user')
227 self.checkSessionFlash(response, 'Successfully deleted user')
221
228
222 def test_delete_user_group_err(self):
229 def test_delete_user_group_err(self):
@@ -229,7 +236,8 b' class TestAdminUsersController(TestContr'
229
236
230 new_user = Session().query(User)\
237 new_user = Session().query(User)\
231 .filter(User.username == username).one()
238 .filter(User.username == username).one()
232 response = self.app.delete(url('user', id=new_user.user_id))
239 response = self.app.post(url('user', id=new_user.user_id),
240 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
233 self.checkSessionFlash(response, 'User "%s" still '
241 self.checkSessionFlash(response, 'User "%s" still '
234 'owns 1 user groups and cannot be removed. '
242 'owns 1 user groups and cannot be removed. '
235 'Switch owners or remove those user groups: '
243 'Switch owners or remove those user groups: '
@@ -241,7 +249,8 b' class TestAdminUsersController(TestContr'
241
249
242 fixture.destroy_user_group(ug.users_group_id)
250 fixture.destroy_user_group(ug.users_group_id)
243
251
244 response = self.app.delete(url('user', id=new_user.user_id))
252 response = self.app.post(url('user', id=new_user.user_id),
253 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
245 self.checkSessionFlash(response, 'Successfully deleted user')
254 self.checkSessionFlash(response, 'Successfully deleted user')
246
255
247 def test_show(self):
256 def test_show(self):
@@ -132,10 +132,11 b' class TestChangeSetCommentsController(Te'
132 self.assertEqual(len(comments), 1)
132 self.assertEqual(len(comments), 1)
133 comment_id = comments[0].comment_id
133 comment_id = comments[0].comment_id
134
134
135 self.app.delete(url(controller='changeset',
135 self.app.post(url(controller='changeset',
136 action='delete_comment',
136 action='delete_comment',
137 repo_name=HG_REPO,
137 repo_name=HG_REPO,
138 comment_id=comment_id))
138 comment_id=comment_id),
139 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
139
140
140 comments = ChangesetComment.query().all()
141 comments = ChangesetComment.query().all()
141 self.assertEqual(len(comments), 0)
142 self.assertEqual(len(comments), 0)
@@ -96,7 +96,8 b' class _BaseTestCase(object):'
96 )
96 )
97
97
98 # remove this fork
98 # remove this fork
99 response = self.app.delete(url('delete_repo', repo_name=fork_name))
99 response = self.app.post(url('delete_repo', repo_name=fork_name),
100 params={'_method': 'delete', '_authentication_token': self.authentication_token()})
100
101
101 def test_fork_create_into_group(self):
102 def test_fork_create_into_group(self):
102 self.log_user()
103 self.log_user()
@@ -57,7 +57,8 b' class TestMyAccountController(TestContro'
57 self.log_user()
57 self.log_user()
58 response = self.app.get(url('my_account_emails'))
58 response = self.app.get(url('my_account_emails'))
59 response.mustcontain('No additional emails specified')
59 response.mustcontain('No additional emails specified')
60 response = self.app.post(url('my_account_emails'),)
60 response = self.app.post(url('my_account_emails'),
61 {'_authentication_token': self.authentication_token()})
61 self.checkSessionFlash(response, 'Please enter an email address')
62 self.checkSessionFlash(response, 'Please enter an email address')
62
63
63 def test_my_account_my_emails_add_remove(self):
64 def test_my_account_my_emails_add_remove(self):
General Comments 0
You need to be logged in to leave comments. Login now