comparison roundup/cgi/client.py @ 1685:b6621f8bd496 maint-0.5

backported XSS message cleaning fix [SF#757128]
author Richard Jones <richard@users.sourceforge.net>
date Tue, 24 Jun 2003 03:33:56 +0000
parents 02ed2b7180e0
children 03170eb33b82
comparison
equal deleted inserted replaced
1683:5127c4560f1e 1685:b6621f8bd496
1 # $Id: client.py,v 1.65.2.9 2003-06-19 23:02:32 richard Exp $ 1 # $Id: client.py,v 1.65.2.10 2003-06-24 03:33:56 richard Exp $
2 2
3 __doc__ = """ 3 __doc__ = """
4 WWW request handler (also used in the stand-alone server). 4 WWW request handler (also used in the stand-alone server).
5 """ 5 """
6 6
45 # doing Role stuff through the web - make sure Admin can 45 # doing Role stuff through the web - make sure Admin can
46 p = security.addPermission(name="Web Roles", 46 p = security.addPermission(name="Web Roles",
47 description="User may manipulate user Roles through the web") 47 description="User may manipulate user Roles through the web")
48 security.addPermissionToRole('Admin', p) 48 security.addPermissionToRole('Admin', p)
49 49
50 def clean_message(match, ok={'a':1,'i':1,'b':1,'br':1}): 50 # used to clean messages passed through CGI variables - HTML-escape any tag
51 # that isn't <a href="">, <i>, <b> and <br> (including XHTML variants) so
52 # that people can't pass through nasties like <script>, <iframe>, ...
53 CLEAN_MESSAGE_RE = r'(<(/?(.*?)(\s*href="[^"]")?\s*/?)>)'
54 def clean_message(message, mc=re.compile(CLEAN_MESSAGE_RE, re.I)):
55 return mc.sub(clean_message_callback, message)
56 def clean_message_callback(match, ok={'a':1,'i':1,'b':1,'br':1}):
51 ''' Strip all non <a>,<i>,<b> and <br> tags from a string 57 ''' Strip all non <a>,<i>,<b> and <br> tags from a string
52 ''' 58 '''
53 if ok.has_key(match.group(2)): 59 if ok.has_key(match.group(3).lower()):
54 return match.group(1) 60 return match.group(1)
55 return '&lt;%s&gt;'%match.group(2) 61 return '&lt;%s&gt;'%match.group(2)
56 62
57 class Client: 63 class Client:
58 ''' Instantiate to handle one CGI request. 64 ''' Instantiate to handle one CGI request.
254 self.user = user 260 self.user = user
255 261
256 # reopen the database as the correct user 262 # reopen the database as the correct user
257 self.opendb(self.user) 263 self.opendb(self.user)
258 264
259 def determine_context(self, dre=re.compile(r'([^\d]+)(\d+)'), 265 def determine_context(self, dre=re.compile(r'([^\d]+)(\d+)')):
260 mc=re.compile(r'(</?(.*?)>)')):
261 ''' Determine the context of this page from the URL: 266 ''' Determine the context of this page from the URL:
262 267
263 The URL path after the instance identifier is examined. The path 268 The URL path after the instance identifier is examined. The path
264 is generally only one entry long. 269 is generally only one entry long.
265 270
337 if self.form.has_key(':template'): 342 if self.form.has_key(':template'):
338 self.template = self.form[':template'].value 343 self.template = self.form[':template'].value
339 344
340 # see if we were passed in a message 345 # see if we were passed in a message
341 if self.form.has_key(':ok_message'): 346 if self.form.has_key(':ok_message'):
342 msg = mc.sub(clean_message, self.form[':ok_message'].value) 347 msg = clean_message(self.form[':ok_message'].value)
343 self.ok_message.append(msg) 348 self.ok_message.append(msg)
344 if self.form.has_key(':error_message'): 349 if self.form.has_key(':error_message'):
345 msg = mc.sub(clean_message, self.form[':error_message'].value) 350 msg = clean_message(self.form[':error_message'].value)
346 self.error_message.append(msg) 351 self.error_message.append(msg)
347 352
348 def serve_file(self, designator, dre=re.compile(r'([^\d]+)(\d+)')): 353 def serve_file(self, designator, dre=re.compile(r'([^\d]+)(\d+)')):
349 ''' Serve the file from the content property of the designated item. 354 ''' Serve the file from the content property of the designated item.
350 ''' 355 '''

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