Bug 2498188 (CVE-2026-15154) - CVE-2026-15154 guardrails-detectors: guardrails-detectors: Unauthenticated Regular-Expression Denial of Service (ReDoS) via detector_params.regex
Summary: CVE-2026-15154 guardrails-detectors: guardrails-detectors: Unauthenticated Re...
Keywords:
Status: NEW
Alias: CVE-2026-15154
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security DevOps Team
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-07-08 18:44 UTC by OSIDB Bzimport
Modified: 2026-07-08 19:46 UTC (History)
0 users

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-07-08 18:44:50 UTC
The built-in regex detector in \`guardrails-detectors\` (trustyai-explainability/guardrails-detectors) accepts attacker-controlled regular expressions over its public detection API with no compilation safeguards (no timeout, no complexity/length limit), enabling a single HTTP request to pin a worker process at 100% CPU indefinitely (ReDoS).

\`RegexDetectorRegistry.handle_request()\` (\`detectors/built_in/regex_detectors.py\`) iterates every entry in the request body's \`detector_params["regex"]\` list. Any entry that isn't one of the built-in registry keys falls through to the \`else\` branch and is passed verbatim as the pattern to Python's \`re.finditer()\`:

\`\`\`python
else:
    func_name = "custom_regex"
    with self.instrument_runtime(func_name):
        new_detections += get_regex_detections(content, regex, "regex", "custom-regex")
\`\`\`

Python's \`re\` engine is backtracking-based with no execution timeout. A single request such as:

\`\`\`json
{"contents": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!"],
 "detector_params": {"regex": ["(a+)+$"]}}
\`\`\`

causes catastrophic backtracking, pinning the handling worker at 100% CPU indefinitely. The built-in image starts uvicorn with 4 workers (\`detectors/Dockerfile.builtIn:23\`), so 4 concurrent requests exhaust the whole detector. Depending on the FMS-Guardrails Orchestrator's fail-open/fail-closed configuration for detector unavailability, this causes either a denial of service of the whole guardrails-mediated LLM pipeline, or unfiltered/unmoderated access to the LLM (a guardrail bypass). There is also no length limit on the analyzed \`contents\` strings, so the attacker also controls the haystack size.

Independently verified against the current \`main\` branch (HEAD \`747a4d3\`) of trustyai-explainability/guardrails-detectors, the vulnerable code path is unchanged. This code was introduced during the Python migration of the built-in detectors and has never shipped in a tagged release (the last tag, \`v0.3.0\`, predates this file); Red Hat OpenShift AI consumes this project directly from \`main\`, not from a tagged release.

The project's maintainer (Rob Geada) confirmed on the source Jira issue that end users don't call the detector API directly; requests are normally brokered through the FMS-Guardrails Orchestrator or another proxy application, reflected in the agreed CVSS vector's \`AV:A\`.

Reported via Red Hat's internal Project Glasswing (Mythos) security audit of RHOAI. Source: RHOAIENG-71918 (https://redhat.atlassian.net/browse/RHOAIENG-71918).


Note You need to log in before you can comment on or make changes to this bug.