From e11661ff3ebdeda35c024041c124b0824f1682b0 Mon Sep 17 00:00:00 2001 From: Unrud Date: Sun, 19 Jan 2020 18:39:31 +0100 Subject: [PATCH] Protect against XML DOS attacks Only XML content from authenticated users is parsed. --- radicale/app/__init__.py | 3 ++- radicale/tests/test_base.py | 4 ++-- setup.py | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/radicale/app/__init__.py b/radicale/app/__init__.py index 5c445b9..54f2fd1 100644 --- a/radicale/app/__init__.py +++ b/radicale/app/__init__.py @@ -37,6 +37,7 @@ import zlib from http import client from xml.etree import ElementTree as ET +import defusedxml.ElementTree as DefusedET import pkg_resources from radicale import (auth, httputils, log, pathutils, rights, storage, web, @@ -355,7 +356,7 @@ class Application( if not content: return None try: - xml_content = ET.fromstring(content) + xml_content = DefusedET.fromstring(content) except ET.ParseError as e: logger.debug("Request content (Invalid XML):\n%s", content) raise RuntimeError("Failed to parse XML: %s" % e) from e diff --git a/radicale/tests/test_base.py b/radicale/tests/test_base.py index 3d60f79..ca69a3f 100644 --- a/radicale/tests/test_base.py +++ b/radicale/tests/test_base.py @@ -26,9 +26,9 @@ import posixpath import shutil import sys import tempfile -import xml.etree.ElementTree as ET from functools import partial +import defusedxml.ElementTree as DefusedET import pytest from radicale import Application, config, storage @@ -1161,7 +1161,7 @@ class BaseRequestsMixIn: if sync_token and status == 409: return None, None assert status == 207 - xml = ET.fromstring(answer) + xml = DefusedET.fromstring(answer) sync_token = xml.find("{DAV:}sync-token").text.strip() assert sync_token return sync_token, xml diff --git a/setup.py b/setup.py index cd66cbb..2b5ddde 100755 --- a/setup.py +++ b/setup.py @@ -73,7 +73,8 @@ setup( exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), package_data={"radicale": WEB_FILES}, entry_points={"console_scripts": ["radicale = radicale.__main__:run"]}, - install_requires=["passlib", "vobject>=0.9.6", "python-dateutil>=2.7.3"], + install_requires=["defusedxml", "passlib", "vobject>=0.9.6", + "python-dateutil>=2.7.3"], setup_requires=pytest_runner, tests_require=tests_require, extras_require={