From 724d0dce6e2ac5e2054f4c524d9d5e177106f11b Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sat, 29 May 2010 00:44:05 +0200 Subject: security fix: filters.RequestLogWSGIFilter must escape strings --- wsgitools/filters.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/wsgitools/filters.py b/wsgitools/filters.py index 64038c8..11623ef 100644 --- a/wsgitools/filters.py +++ b/wsgitools/filters.py @@ -202,6 +202,20 @@ class WSGIFilterMiddleware: (reqfilter.filter_data(data) for data in ret), late_append_data()) +# Using map and lambda here since pylint cannot handle list comprehension in +# default arguments. Also note that neither ' nor " are considered printable. +def escape_string(string, replacer=list(map( + lambda i: chr(i) if chr(i).isalnum() or + chr(i) in '!#$%&()*+,-./:;<=>?@[\\]^_`{|}~ ' else + r"\x%2.2x" % i, + range(256)))): + """Encodes non-printable characters in a string using \\xXX escapes. + + @type string: str + @rtype: str + """ + return "".join(replacer[ord(char)] for char in string) + __all__.append("RequestLogWSGIFilter") class RequestLogWSGIFilter(BaseWSGIFilter): """This filter logs all requests in the apache log file format.""" @@ -263,16 +277,17 @@ class RequestLogWSGIFilter(BaseWSGIFilter): def handle_close(self): """BaseWSGIFilter interface""" line = '%s %s - [%s]' % (self.remote, self.user, self.time) - line = '%s "%s %s' % (line, self.reqmethod, self.path) + line = '%s "%s %s' % (line, escape_string(self.reqmethod), + escape_string(self.path)) if self.proto is not None: line = "%s %s" % (line, self.proto) line = '%s" %s %d' % (line, self.status, self.length) if self.referrer is not None: - line = '%s "%s"' % (line, self.referrer) + line = '%s "%s"' % (line, escape_string(self.referrer)) else: line += " -" if self.useragent is not None: - line = '%s "%s"' % (line, self.useragent) + line = '%s "%s"' % (line, escape_string(self.useragent)) else: line += " -" self.log.write("%s\n" % line) -- cgit v1.2.3