From 00d8b08341a70e32fbc35081f5314925d6185fd0 Mon Sep 17 00:00:00 2001 From: Pieter Naaijkens Date: Tue, 14 Jun 2011 16:21:56 +0200 Subject: [PATCH] Merge URI sanitize fix --- radicale/__init__.py | 13 +++++++++++++ radicale/ical.py | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/radicale/__init__.py b/radicale/__init__.py index c82c125..3215af7 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -31,6 +31,7 @@ should have been included in this package. import os import pprint import base64 +import posixpath import socket import ssl import wsgiref.simple_server @@ -38,9 +39,11 @@ import wsgiref.simple_server # pylint: disable=F0401 try: from http import client, server + import urllib.parse as urllib except ImportError: import httplib as client import BaseHTTPServer as server + import urllib # pylint: enable=F0401 from radicale import acl, config, ical, log, xmlutils @@ -137,6 +140,12 @@ class Application(object): pass raise UnicodeDecodeError + @staticmethod + def sanitize_uri(uri): + """Clean URI: unquote and remove /../ to prevent access to other data.""" + uri = posixpath.normpath(urllib.unquote(uri)) + return uri + def __call__(self, environ, start_response): """Manage a request.""" log.LOGGER.info("%s request at %s received" % ( @@ -144,6 +153,10 @@ class Application(object): headers = pprint.pformat(self.headers_log(environ)) log.LOGGER.debug("Request headers:\n%s" % headers) + # Sanitize request URI + environ["PATH_INFO"] = self.sanitize_uri(environ["PATH_INFO"]) + log.LOGGER.debug("Sanitized path: %s", environ["PATH_INFO"]) + # Get content content_length = int(environ.get("CONTENT_LENGTH") or 0) if content_length: diff --git a/radicale/ical.py b/radicale/ical.py index 96ead4f..c8c2656 100644 --- a/radicale/ical.py +++ b/radicale/ical.py @@ -183,7 +183,8 @@ class Calendar(object): The ``path`` is relative to the storage folder. """ - attributes = posixpath.normpath(path.strip("/")).split("/") + # First do normpath and then strip, to prevent access to FOLDER/../ + attributes = posixpath.normpath(path).strip("/").split("/") if not attributes: return None if attributes[-1].endswith(".ics"):