Bandit [B411]: use defusedxml to prevent remote XML attacks

- putting xmlrpc stuff into koji.xmlrpcplus
- adding koji.xmlrpcplus.xmlrpc_server to refer
- replacing refs of original xmlrpc.client.dumps to enhanced
  koji.xmlrpcplus.dumps

fixes: #3964
This commit is contained in:
Yu Ming Zhu 2024-01-15 13:38:41 +00:00 committed by Tomas Kopecek
parent a96b5a9b07
commit f41b8c70a7
11 changed files with 46 additions and 38 deletions

View file

@ -38,7 +38,6 @@ import tempfile
import threading
import time
import traceback
import xmlrpc.client
# urllib is required by the SCM class which is substituted into this file
# do not remove the import below
import urllib # noqa: F401
@ -46,6 +45,7 @@ import zipfile
from configparser import RawConfigParser
from optparse import OptionParser
from defusedxml import xmlrpc
import six # noqa: F401, needed for imported code
@ -53,6 +53,9 @@ MANAGER_PORT = 7000
KOJIKAMID = True
# patching xmlrpc to protect against XML related attacks
xmlrpc.monkey_patch()
# INSERT kojikamid dup #
@ -635,7 +638,9 @@ def get_mgmt_server():
macaddr, gateway = find_net_info()
logger.debug('found MAC address %s, connecting to %s:%s',
macaddr, gateway, MANAGER_PORT)
server = xmlrpc.client.ServerProxy('http://%s:%s/' % (gateway, MANAGER_PORT), allow_none=True)
server = xmlrpc.xmlrpc_client.ServerProxy(
'http://%s:%s/' % (gateway, MANAGER_PORT), allow_none=True
)
# we would set a timeout on the socket here, but that is apparently not
# supported by python/cygwin/Windows
task_port = server.getPort(macaddr)

View file

@ -35,8 +35,6 @@ import subprocess
import sys
import threading
import time
import xmlrpc
import xmlrpc.server
from contextlib import closing
from optparse import OptionParser
@ -45,6 +43,7 @@ import libxml2
import requests
import koji
from koji.xmlrpcplus import dumps, Fault, loads, xmlrpc_client, xmlrpc_server
import koji.util
from koji.daemon import SCM, TaskManager
# TaskHandlers are required to be imported, do not remove them
@ -295,15 +294,15 @@ def main(options, session):
# Tasks for handling VM lifecycle
####################
class DaemonXMLRPCServer(xmlrpc.server.SimpleXMLRPCServer):
class DaemonXMLRPCServer(xmlrpc_server.SimpleXMLRPCServer):
allow_reuse_address = True
def __init__(self, addr, port):
if sys.version_info[:2] <= (2, 4):
xmlrpc.server.SimpleXMLRPCServer.__init__(self, (addr, port),
xmlrpc_server.SimpleXMLRPCServer.__init__(self, (addr, port),
logRequests=False)
else:
xmlrpc.server.SimpleXMLRPCServer.__init__(self, (addr, port),
xmlrpc_server.SimpleXMLRPCServer.__init__(self, (addr, port),
logRequests=False,
allow_none=True)
self.logger = logging.getLogger('koji.vm.DaemonXMLRPCServer')
@ -312,7 +311,7 @@ class DaemonXMLRPCServer(xmlrpc.server.SimpleXMLRPCServer):
def server_close(self):
self.active = False
xmlrpc.server.SimpleXMLRPCServer.server_close(self)
xmlrpc_server.SimpleXMLRPCServer.server_close(self)
def handle_while_active(self):
while self.active:
@ -333,20 +332,20 @@ class DaemonXMLRPCServer(xmlrpc.server.SimpleXMLRPCServer):
# Copy and paste from SimpleXMLRPCServer, with the addition of passing
# allow_none=True to xmlrpclib.dumps()
def _marshaled_dispatch(self, data, dispatch_method=None):
params, method = xmlrpc.client.loads(data)
params, method = loads(data)
try:
if dispatch_method is not None:
response = dispatch_method(method, params)
else:
response = self._dispatch(method, params)
response = (response,)
response = xmlrpc.client.dumps(response, methodresponse=1, allow_none=True)
except xmlrpc.client.Fault as fault:
response = xmlrpc.client.dumps(fault)
response = dumps(response, methodresponse=1, allow_none=True)
except Fault as fault:
response = dumps(fault)
except Exception:
# report exception back to server
response = xmlrpc.client.dumps(
xmlrpc.client.Fault(1, "%s:%s" % (sys.exc_info()[0], sys.exc_info()[1]))
response = dumps(
Fault(1, "%s:%s" % (sys.exc_info()[0], sys.exc_info()[1]))
)
return response
@ -480,7 +479,7 @@ class VMExecTask(BaseTaskHandler):
def __init__(self, *args, **kw):
super(VMExecTask, self).__init__(*args, **kw)
self.task_manager = xmlrpc.client.ServerProxy(
self.task_manager = xmlrpc_client.ServerProxy(
'http://%s:%s/' % (self.options.privaddr, self.options.portbase), allow_none=True)
self.port = None
self.server = None