mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 03:36:48 +00:00
fix(instances): add_network escapes posted values
add_network built the interface XML with f-strings, so a posted model or nwfilter could add arbitrary devices to the domain. It is built with lxml now; a missing MAC is left to libvirt instead of address='None'.
This commit is contained in:
parent
e94d69a524
commit
c789406edf
2 changed files with 34 additions and 13 deletions
|
|
@ -1709,23 +1709,21 @@ class wvmInstance(wvmConnect):
|
|||
else:
|
||||
interface_type = "direct"
|
||||
|
||||
# network modes not handled: default is bridge
|
||||
|
||||
xml_iface = f"""
|
||||
<interface type='{interface_type}'>
|
||||
<mac address='{mac_address}'/>"""
|
||||
# Built with lxml so posted values are escaped, never parsed as XML.
|
||||
iface = etree.Element("interface", type=interface_type)
|
||||
if mac_address: # otherwise libvirt generates one
|
||||
etree.SubElement(iface, "mac", address=mac_address)
|
||||
if interface_type == "network":
|
||||
xml_iface += f"""<source network='{source}'/>"""
|
||||
etree.SubElement(iface, "source", network=source)
|
||||
elif interface_type == "direct":
|
||||
xml_iface += f"""<source dev='{source}' mode='bridge'/>"""
|
||||
elif interface_type == "bridge":
|
||||
xml_iface += f"""<source bridge='{source}'/>"""
|
||||
etree.SubElement(iface, "source", dev=source, mode="bridge")
|
||||
else:
|
||||
raise libvirtError(f"'{interface_type}' is an unexpected interface type.")
|
||||
xml_iface += f"""<model type='{model}'/>"""
|
||||
etree.SubElement(iface, "source", bridge=source)
|
||||
if model:
|
||||
etree.SubElement(iface, "model", type=model)
|
||||
if nwfilter:
|
||||
xml_iface += f"""<filterref filter='{nwfilter}'/>"""
|
||||
xml_iface += """</interface>"""
|
||||
etree.SubElement(iface, "filterref", filter=nwfilter)
|
||||
xml_iface = etree.tostring(iface).decode()
|
||||
|
||||
if self.get_status() == 1:
|
||||
self.instance.attachDeviceFlags(xml_iface, VIR_DOMAIN_AFFECT_LIVE)
|
||||
|
|
|
|||
|
|
@ -52,5 +52,28 @@ class TestChangeNetwork(unittest.TestCase):
|
|||
self.assertEqual(flags, VIR_DOMAIN_AFFECT_CONFIG)
|
||||
|
||||
|
||||
class TestAddNetworkXml(unittest.TestCase):
|
||||
def attached(self, **kwargs):
|
||||
from lxml import etree
|
||||
|
||||
inst = stopped_instance()
|
||||
inst.add_network(**kwargs)
|
||||
return etree.fromstring(inst.instance.attachDeviceFlags.call_args[0][0])
|
||||
|
||||
def test_posted_values_cannot_inject_elements(self):
|
||||
iface = self.attached(
|
||||
mac_address="52:54:00:00:00:05",
|
||||
source="default",
|
||||
model="virtio'/><filesystem type='mount'/><model type='x",
|
||||
nwfilter="f'/><evil/>",
|
||||
)
|
||||
self.assertEqual([el.tag for el in iface], ["mac", "source", "model", "filterref"])
|
||||
self.assertEqual(iface.find("model").get("type"), "virtio'/><filesystem type='mount'/><model type='x")
|
||||
|
||||
def test_missing_mac_is_left_to_libvirt(self):
|
||||
iface = self.attached(mac_address="", source="default")
|
||||
self.assertIsNone(iface.find("mac"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue