comparison roundup/cgi/client.py @ 1684:b87c40d1b8fb

fix hackish message escaping [SF#757128]
author Richard Jones <richard@users.sourceforge.net>
date Tue, 24 Jun 2003 03:30:40 +0000
parents ee730d990989
children aca6de3e5eac
comparison
equal deleted inserted replaced
1682:25350acdcb82 1684:b87c40d1b8fb
1 # $Id: client.py,v 1.119 2003-06-10 22:55:30 richard Exp $ 1 # $Id: client.py,v 1.120 2003-06-24 03:30:30 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
66 # doing Role stuff through the web - make sure Admin can 66 # doing Role stuff through the web - make sure Admin can
67 p = security.addPermission(name="Web Roles", 67 p = security.addPermission(name="Web Roles",
68 description="User may manipulate user Roles through the web") 68 description="User may manipulate user Roles through the web")
69 security.addPermissionToRole('Admin', p) 69 security.addPermissionToRole('Admin', p)
70 70
71 def clean_message(match, ok={'a':1,'i':1,'b':1,'br':1}): 71 # used to clean messages passed through CGI variables - HTML-escape any tag
72 # that isn't <a href="">, <i>, <b> and <br> (including XHTML variants) so
73 # that people can't pass through nasties like <script>, <iframe>, ...
74 CLEAN_MESSAGE_RE = r'(<(/?(.*?)(\s*href="[^"]")?\s*/?)>)'
75 def clean_message(message, mc=re.compile(CLEAN_MESSAGE_RE, re.I)):
76 return mc.sub(clean_message_callback, message)
77 def clean_message_callback(match, ok={'a':1,'i':1,'b':1,'br':1}):
72 ''' Strip all non <a>,<i>,<b> and <br> tags from a string 78 ''' Strip all non <a>,<i>,<b> and <br> tags from a string
73 ''' 79 '''
74 if ok.has_key(match.group(2)): 80 if ok.has_key(match.group(3).lower()):
75 return match.group(1) 81 return match.group(1)
76 return '&lt;%s&gt;'%match.group(2) 82 return '&lt;%s&gt;'%match.group(2)
77 83
78 class Client: 84 class Client:
79 ''' Instantiate to handle one CGI request. 85 ''' Instantiate to handle one CGI request.
346 self.user = user 352 self.user = user
347 353
348 # reopen the database as the correct user 354 # reopen the database as the correct user
349 self.opendb(self.user) 355 self.opendb(self.user)
350 356
351 def determine_context(self, dre=re.compile(r'([^\d]+)(\d+)'), 357 def determine_context(self, dre=re.compile(r'([^\d]+)(\d+)')):
352 mc=re.compile(r'(</?(.*?)>)')):
353 ''' Determine the context of this page from the URL: 358 ''' Determine the context of this page from the URL:
354 359
355 The URL path after the instance identifier is examined. The path 360 The URL path after the instance identifier is examined. The path
356 is generally only one entry long. 361 is generally only one entry long.
357 362
395 for key in self.form.keys(): 400 for key in self.form.keys():
396 if self.FV_TEMPLATE.match(key): 401 if self.FV_TEMPLATE.match(key):
397 template_override = self.form[key].value 402 template_override = self.form[key].value
398 elif self.FV_OK_MESSAGE.match(key): 403 elif self.FV_OK_MESSAGE.match(key):
399 ok_message = self.form[key].value 404 ok_message = self.form[key].value
400 ok_message = mc.sub(clean_message, ok_message) 405 ok_message = clean_message(ok_message)
401 elif self.FV_ERROR_MESSAGE.match(key): 406 elif self.FV_ERROR_MESSAGE.match(key):
402 error_message = self.form[key].value 407 error_message = self.form[key].value
403 error_message = mc.sub(clean_message, error_message) 408 error_message = clean_message(error_message)
404 409
405 # determine the classname and possibly nodeid 410 # determine the classname and possibly nodeid
406 path = self.path.split('/') 411 path = self.path.split('/')
407 if not path or path[0] in ('', 'home', 'index'): 412 if not path or path[0] in ('', 'home', 'index'):
408 if template_override is not None: 413 if template_override is not None:

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