mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
Four lookups built XPath expressions from values that come from requests (CodeQL py/xpath-injection, plus get_capabilities, which CodeQL did not flag; the pages are for superusers): - The architecture in the create wizard's URLs went into arch[@name='...'] in get_emulator, get_machine_types and get_capabilities: "nope' or '1'='1" matched every architecture. It is now an XPath variable ($arch), which is never parsed as XPath. - Network filter rules were found with a predicate built from the posted action, direction and priority: a quote raised SyntaxError (an error page). The rule is now found by comparing its attributes. - unset_qos put the posted direction into the path, so "*" removed every bandwidth setting. It accepts inbound and outbound, as set_qos does; the network page shows an error for anything else. No other XPath in vrtManager is built from a value; the remaining expressions are constants. The tests fail on the previous code.
65 lines
2.7 KiB
Python
65 lines
2.7 KiB
Python
"""Values from requests do not change the XPath queries they are used in."""
|
|
|
|
import unittest
|
|
|
|
from django.conf import settings
|
|
|
|
if not settings.configured:
|
|
settings.configure(MAC_OUI="52:54:10")
|
|
|
|
from vrtManager.connection import wvmConnect
|
|
from vrtManager.network import wvmNetwork
|
|
from vrtManager.nwfilters import wvmNWFilter
|
|
|
|
CAPS = """<capabilities><guest><arch name='x86_64'><wordsize>64</wordsize><emulator>/usr/bin/qemu-x86</emulator>
|
|
<machine canonical='pc-q35'>q35</machine></arch>
|
|
<arch name='aarch64'><emulator>/usr/bin/qemu-arm</emulator><machine>virt</machine></arch></guest></capabilities>"""
|
|
|
|
FILTER = """<filter name='f'><rule action='drop' direction='in' priority='1'><tcp/></rule>
|
|
<rule action='drop' direction='in' priority='2'><udp/></rule></filter>"""
|
|
|
|
|
|
class FakeConn:
|
|
def __init__(self):
|
|
self.defined = None
|
|
|
|
def networkDefineXML(self, xml):
|
|
self.defined = xml
|
|
|
|
|
|
class XPathValueTests(unittest.TestCase):
|
|
def setUp(self):
|
|
self.conn = wvmConnect.__new__(wvmConnect)
|
|
self.conn.get_cap_xml = lambda: CAPS
|
|
|
|
def test_arch_lookups(self):
|
|
self.assertEqual(self.conn.get_emulator("x86_64"), "/usr/bin/qemu-x86")
|
|
self.assertEqual(self.conn.get_machine_types("aarch64"), ["virt"])
|
|
injected = "nope' or '1'='1"
|
|
self.assertIsNone(self.conn.get_emulator(injected))
|
|
self.assertEqual(self.conn.get_machine_types(injected), [])
|
|
self.assertEqual(self.conn.get_capabilities(injected), {})
|
|
|
|
def test_nwfilter_rule_is_matched_by_its_attributes(self):
|
|
nwf = wvmNWFilter.__new__(wvmNWFilter)
|
|
nwf._XMLDesc = lambda flags: FILTER
|
|
# values with quotes or brackets are compared, not parsed as XPath
|
|
self.assertEqual(nwf.delete_rule("drop'][@priority='2", "in", "1").count("<rule "), 2)
|
|
self.assertEqual(nwf.delete_rule("it's", "in", "1").count("<rule "), 2)
|
|
kept = nwf.delete_rule("drop", "in", "2")
|
|
self.assertEqual(kept.count("<rule "), 1)
|
|
self.assertIn("priority=\"1\"", kept)
|
|
# add_rule appends to the matching rule only
|
|
added = nwf.add_rule("<rule action='drop' direction='in' priority='2'><icmp/></rule>")
|
|
self.assertEqual(added.count("<rule "), 2)
|
|
self.assertIn("<icmp", added.split('priority="2"')[1])
|
|
|
|
def test_qos_direction_must_be_known(self):
|
|
net = wvmNetwork.__new__(wvmNetwork)
|
|
net.wvm = FakeConn()
|
|
net._XMLDesc = lambda flags: "<network><bandwidth><inbound average='1'/><outbound average='2'/></bandwidth></network>"
|
|
with self.assertRaises(ValueError):
|
|
net.unset_qos("*")
|
|
net.unset_qos("inbound")
|
|
self.assertNotIn("inbound", net.wvm.defined)
|
|
self.assertIn("outbound", net.wvm.defined)
|