diff --git a/CHANGES.txt b/CHANGES.txt index 746ac31c..738efcb4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -81,6 +81,9 @@ Features: Rouillard) - added fuzz testing for some code. Found issue2551382 and others. (John Rouillard) +- issue2551116 - Replace xmlrpclib (xmlrpc.client) with defusedxml. + Added support for defusedxml to better secure the xmlrpc + endpoint. (John Rouillard) 2024-07-13 2.4.0 diff --git a/doc/installation.txt b/doc/installation.txt index bc6f23bf..7e05ec5e 100644 --- a/doc/installation.txt +++ b/doc/installation.txt @@ -255,6 +255,11 @@ jinja2 its TEMPLATE-INFO.txt file) you need to have the jinja2_ template engine installed. +defusedxml + If you are going to enable and use the XMLRPC endpoint, you should + install the defusedxml_ module. It will still work with the default + xmlrpc standard library, but it will log a warning when used. + .. _install/docutils: docutils @@ -2371,6 +2376,7 @@ the test. .. _apache: https://httpd.apache.org/ .. _brotli: https://pypi.org/project/Brotli/ .. _`developer's guide`: developers.html +.. _defusedxml: https://pypi.org/project/defusedxml/ .. _docutils: https://pypi.org/project/docutils/ .. _flup: https://pypi.org/project/flup/ .. _gpg: https://www.gnupg.org/software/gpgme/index.html diff --git a/doc/upgrading.txt b/doc/upgrading.txt index 063ce02c..e1d163d3 100644 --- a/doc/upgrading.txt +++ b/doc/upgrading.txt @@ -159,6 +159,36 @@ following diff:: add the lines marked with ``+`` in the file in the location after check_main is assigned. +Defusedxml support improves XMLRPC security (optional) +------------------------------------------------------ + +This release adds support for the defusedxml_ module. If it is +installed it will be automatically used. The default xmlrpc module in +the standard library has known issues when parsing crafted XML. It can +take a lot of CPU time and consume large amounts of memory with small +payloads. + +When the XMLRPC endpoint is used without defusedxml, it will log a +warning to the log file. The log entry can be disabled by adding:: + + + from roundup.cgi import client + client.WARN_FOR_MISSING_DEFUSEDXML = False + +to the ``interfaces.py`` file in the tracker home. (Create the file if +it is missing.) + +XMLRPC access is enabled by default in the classic and other trackers. +Upgrading to defusedxml is considered optional because the XMLRPC +endpoint can be disabled in the tracker's ``config.ini``. Also +``Xmlrpc Access`` can be removed from the ``Users`` role by commenting +out a line in ``schema.py``. + +If you have enabled the xmlrpc endpoint, you should install +defusedxml. + +.. _defusedxml: https://pypi.org/project/defusedxml/ + More secure session cookie handling (info) ------------------------------------------ diff --git a/doc/xmlrpc.txt b/doc/xmlrpc.txt index bf2d939b..fc25a983 100644 --- a/doc/xmlrpc.txt +++ b/doc/xmlrpc.txt @@ -79,7 +79,8 @@ Both the standalone and embedded roundup XML endpoints used the default python XML parser. This parser is know to have security issues. For details see: https://pypi.org/project/defusedxml/. You may wish to use the rest interface which doesn't have the same -issues. Patches with tests to roundup to use defusedxml are welcome. +issues. If you install defusedxml, it will be automatically used to add +some additional protection. .. caution:: diff --git a/roundup/anypy/xmlrpc_.py b/roundup/anypy/xmlrpc_.py index 37ce7ea0..9d39e2e0 100644 --- a/roundup/anypy/xmlrpc_.py +++ b/roundup/anypy/xmlrpc_.py @@ -1,6 +1,18 @@ try: # Python 3+. from xmlrpc import client, server + # If client.defusedxml == False, client.py will warn that + # xmlrpc is insecure and defusedxml should be installed. + client.defusedxml=False + try: + from defusedxml import xmlrpc + xmlrpc.monkey_patch() + # figure out how to allow user to set xmlrpc.MAX_DATA = bytes + client.defusedxml=True + except ImportError: + # use regular xmlrpc with warnings + pass + server.SimpleXMLRPCDispatcher except (ImportError, AttributeError): # Python 2. diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py index 234bb192..33679280 100644 --- a/roundup/cgi/client.py +++ b/roundup/cgi/client.py @@ -101,6 +101,9 @@ def add_message(msg_list, msg, escape=True): msg_list.append(msg) return msg_list # for unittests +# if set to False via interfaces.py do not log a warning when +# xmlrpc is used and defusedxml is not installed. +WARN_FOR_MISSING_DEFUSEDXML = True default_err_msg = ''"""