From 2f5d8cd4faf5cf601a2ac6607a57b4e2d2ed2da8 Mon Sep 17 00:00:00 2001 From: Neil Williams Date: Thu, 7 Nov 2013 00:06:39 -0800 Subject: [PATCH] Add a middleware to sanitize response splitting attempts. Thanks to Jordan Milne (/u/largenocream) for reporting this and joyent/node@3c293ba27250f1885efa8d8db8e75d3ea033c206 for inspiration for this solution. --- r2/r2/config/middleware.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/r2/r2/config/middleware.py b/r2/r2/config/middleware.py index 0a42a77fe..cb7708658 100644 --- a/r2/r2/config/middleware.py +++ b/r2/r2/config/middleware.py @@ -355,6 +355,26 @@ class CleanupMiddleware(object): return self.app(environ, custom_start_response) +class SafetyMiddleware(object): + """Clean up any attempts at response splitting in headers.""" + + has_bad_characters = re.compile("[\r\n]") + sanitizer = re.compile("[\r\n]+[ \t]*") + + def __init__(self, app): + self.app = app + + def __call__(self, environ, start_response): + def safe_start_response(status, headers, exc_info=None): + sanitized = [] + for name, value in headers: + if self.has_bad_characters.search(value): + value = self.sanitizer.sub("", value) + sanitized.append((name, value)) + return start_response(status, sanitized, exc_info) + return self.app(environ, safe_start_response) + + class RedditApp(PylonsApp): def __init__(self, *args, **kwargs): super(RedditApp, self).__init__(*args, **kwargs) @@ -456,4 +476,6 @@ def make_app(global_conf, full_stack=True, **app_conf): static_fallback = StaticTestMiddleware(static_app, g.config['static_path'], g.config['static_domain']) app = Cascade([static_fallback, app]) + app = SafetyMiddleware(app) + return app