Bug 2498188 (CVE-2026-15154)

Summary: CVE-2026-15154 guardrails-detectors: guardrails-detectors: Unauthenticated Regular-Expression Denial of Service (ReDoS) via detector_params.regex
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security DevOps Team <prodsec-dev>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedKeywords: Security
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in `guardrails-detectors`, a component of Red Hat OpenShift AI. This vulnerability, known as Regular Expression Denial of Service (ReDoS), allows a remote attacker to provide specially crafted regular expressions to the public detection API. This can cause catastrophic backtracking, leading to a worker process consuming 100% CPU indefinitely and resulting in a denial of service for the entire guardrails-mediated LLM pipeline.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

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).