Mercurial > p > roundup > code
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 '<%s>'%match.group(2) | 61 return '<%s>'%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 ''' |
