Bug report
Bug description:
Summary
dumps() interpolates the method name directly into <methodName> tags without XML escaping. If an application derives methodname from user input, an attacker can inject XML markup into the request body.
Details
The method name is interpolated into a tuple that is later joined into the final XML string:
|
if methodname: |
|
# a method call |
|
data = ( |
|
xmlheader, |
|
"<methodCall>\n" |
|
"<methodName>", methodname, "</methodName>\n", |
|
data, |
|
"</methodCall>\n" |
|
) |
The tuple is serialized via "".join(data). The method name is written raw into XML without calling the module's escape() helper (used elsewhere, e.g., for string values in dump_unicode).
Reproducer
import xml.etree.ElementTree as ET
from xmlrpc.client import dumps
def main():
payload = 'foo</methodName><injected attr="evil"/><methodName>bar'
result = dumps((), methodname=payload)
root = ET.fromstring(result)
method_names = root.findall("methodName")
assert len(method_names) == 2, (
f"Expected 2 <methodName> elements from injection, got "
f"{len(method_names)}"
)
print("Generated XML:")
print(result)
if __name__ == "__main__":
main()
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
Bug report
Bug description:
Summary
dumps()interpolates the method name directly into<methodName>tags without XML escaping. If an application derivesmethodnamefrom user input, an attacker can inject XML markup into the request body.Details
The method name is interpolated into a tuple that is later joined into the final XML string:
cpython/Lib/xmlrpc/client.py
Lines 963 to 971 in 04fd103
The tuple is serialized via
"".join(data). The method name is written raw into XML without calling the module'sescape()helper (used elsewhere, e.g., for string values indump_unicode).Reproducer
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs