fix an edge case, where mallory can delete comments by bo

This commit is contained in:
posativ 2012-10-23 16:12:36 +02:00
parent 3459b7b9ee
commit ecd4c6b120
3 changed files with 35 additions and 4 deletions

View File

@ -36,10 +36,12 @@ def create(app, environ, request, path):
except ValueError: except ValueError:
return abort(400) return abort(400)
md5 = rv.md5
rv.text = app.markup.convert(rv.text) rv.text = app.markup.convert(rv.text)
response = Response(json.dumps(rv), 201, content_type='application/json') response = Response(json.dumps(rv), 201, content_type='application/json')
response.set_cookie('session-%s-%s' % (urllib.quote(path, ''), rv.id), response.set_cookie('session-%s-%s' % (urllib.quote(path, ''), rv.id),
app.signer.dumps([path, rv.id]), max_age=app.MAX_AGE) app.signer.dumps([path, rv.id, md5]), max_age=app.MAX_AGE)
return response return response
@ -65,14 +67,23 @@ def modify(app, environ, request, path, id):
except (SignatureExpired, BadSignature): except (SignatureExpired, BadSignature):
return abort(403) return abort(403)
if not (rv[0] == '*' or rv == [path, id]): # verify checksum, mallory might skip cookie deletion when he deletes a comment
if app.db.get(path, id).md5 != rv[2]:
abort(403)
if not (rv[0] == '*' or rv[0:2] == [path, id]):
abort(401) abort(401)
if request.method == 'PUT': if request.method == 'PUT':
try: try:
rv = app.db.update(path, id, models.Comment.fromjson(request.data)) rv = app.db.update(path, id, models.Comment.fromjson(request.data))
return Response(json.dumps(rv), 200, content_type='application/json')
except ValueError as e: except ValueError as e:
return Response(unicode(e), 400) return Response(unicode(e), 400)
else:
if request.method == 'DELETE':
rv = app.db.delete(path, id) rv = app.db.delete(path, id)
return Response(json.dumps(rv), 200, content_type='application/json')
response = Response(json.dumps(rv), 200, content_type='application/json')
response.delete_cookie('session-%s-%s' % (urllib.quote(path, ''), id))
return response

View File

@ -5,6 +5,7 @@
import json import json
import time import time
import hashlib
class Comment(object): class Comment(object):
"""This class represents a regular comment. It needs at least a text """This class represents a regular comment. It needs at least a text
@ -56,3 +57,10 @@ class Comment(object):
@property @property
def deleted(self): def deleted(self):
return self.mode == 4 return self.mode == 4
@property
def md5(self):
hv = hashlib.md5()
for key in set(self.fields) - set(['parent', ]):
hv.update(getattr(self, key) or '')
return hv.hexdigest()

View File

@ -115,3 +115,15 @@ class TestComments(unittest.TestCase):
for path in paths: for path in paths:
assert self.get('/comment/' + path) assert self.get('/comment/' + path)
assert self.get('/comment/' + path + '/1') assert self.get('/comment/' + path + '/1')
def testDeleteAndCreateByDifferentUsersButSamePostId(self):
mallory = Client(self.app, Response)
mallory.post('/comment/path/new', data=json.dumps(comment(text='Foo')))
mallory.delete('/comment/path/1')
bob = Client(self.app, Response)
bob.post('/comment/path/new', data=json.dumps(comment(text='Bar')))
assert mallory.delete('/comment/path/1').status_code == 403
assert bob.delete('/comment/path/1').status_code == 200