CVE-2026-21876 Overview
CVE-2026-21876 affects the OWASP ModSecurity Core Rule Set (CRS), a widely deployed collection of generic attack detection rules for web application firewalls (WAFs). The flaw resides in rule 922110, which inspects multipart request charsets. When the chained rule iterates over the MULTIPART_PART_HEADERS collection, the TX:0 and TX:1 capture variables are overwritten on each iteration. Only the final captured value reaches the chained rule, so a malicious charset in an earlier multipart segment is discarded when a later segment carries a legitimate charset. Versions prior to 4.22.0 and 3.3.8 are affected. The issue is classified under [CWE-794] (Reliance on Insufficient Trustworthy Source).
Critical Impact
Attackers can smuggle malicious charsets through multipart uploads by appending a benign part, bypassing CRS charset-based detections.
Affected Products
- OWASP ModSecurity Core Rule Set versions prior to 3.3.8 (3.x branch)
- OWASP ModSecurity Core Rule Set versions prior to 4.22.0 (4.x branch)
- Web application firewalls relying on CRS rule 922110 for multipart charset enforcement
Discovery Timeline
- 2026-01-08 - CVE-2026-21876 published to NVD
- 2026-04-09 - Last updated in NVD database
Technical Details for CVE-2026-21876
Vulnerability Analysis
The defect is a logic flaw in how CRS rule 922110 processes multipart MIME requests. The rule chain is designed to detect disallowed charsets in Content-Type headers of each multipart segment. To do this, the first rule in the chain iterates across the MULTIPART_PART_HEADERS collection and captures matches into transaction variables TX:0 and TX:1. The chained rule then evaluates those capture variables.
Because the capture variables are scalar and reused on every iteration, each pass overwrites the previous capture. By the time the chained rule executes, only the last iteration's values remain. An attacker who places a malicious charset in an early multipart segment and a benign charset in the final segment effectively erases the evidence the chained rule needs to fire. The result is a WAF detection bypass for charset-based attacks against multipart endpoints.
Root Cause
The root cause is improper handling of capture variables inside an iterating ModSecurity rule chain. Capture variables are not preserved per iteration, and the chained rule does not consume them before the next iteration occurs. This violates the assumption that every matched part is independently evaluated, which [CWE-794] characterizes as reliance on insufficient trustworthy source.
Attack Vector
The attack is network-based, requires no authentication, and no user interaction. An attacker submits a crafted multipart/form-data request to any protected endpoint. The request contains at least two parts: an early part declaring a malicious or disallowed charset that the application later mishandles, and a trailing part declaring a benign charset such as utf-8. Rule 922110 evaluates only the final capture, allowing the request to pass and reach backend application logic that may decode the malicious payload.
No working code is reproduced here. The mechanism is documented in the GitHub Security Advisory GHSA-36fv-25j3-r2c5 and the upstream fixes in commit 80d80473 and commit 9917985d.
Detection Methods for CVE-2026-21876
Indicators of Compromise
- Inbound multipart/form-data requests containing multiple parts where at least one part declares an unusual or non-standard charset value in its Content-Type header.
- Multipart requests where charset declarations differ between segments, particularly where the final segment uses a common charset such as utf-8 while preceding segments specify uncommon encodings.
- Web server logs showing successful POST requests to file upload or form endpoints lacking corresponding CRS rule 922110 alerts despite suspicious charset patterns.
Detection Strategies
- Audit WAF logs for 922110 rule firings before and after upgrading to CRS 4.22.0 or 3.3.8 to quantify previously missed events.
- Implement supplementary rules that evaluate each multipart segment header independently rather than relying on capture variables in a chained iteration.
- Inspect raw request bodies at the reverse proxy or application layer to compare charset declarations against an allow-list of permitted encodings.
Monitoring Recommendations
- Track CRS version inventory across all WAF deployments and alert on instances running versions below 4.22.0 or 3.3.8.
- Monitor for repeated multipart submissions from single source addresses targeting upload, profile, or import endpoints.
- Correlate WAF telemetry with backend application logs to surface requests that bypass charset checks but produce decoding errors or anomalous behavior downstream.
How to Mitigate CVE-2026-21876
Immediate Actions Required
- Upgrade the OWASP ModSecurity Core Rule Set to version 4.22.0 for 4.x deployments or 3.3.8 for 3.x deployments.
- Validate the upgrade by submitting test multipart requests with multiple charset declarations and confirming rule 922110 fires on each malicious segment.
- Review WAF blocking mode and ensure paranoia-level settings align with the application's risk profile after the upgrade.
Patch Information
The maintainers fixed the issue in CRS Release v4.22.0 and CRS Release v3.3.8. The fix restructures rule 922110 so each iteration of MULTIPART_PART_HEADERS is evaluated against the chained condition before the next iteration overwrites the capture variables. See the GitHub Security Advisory GHSA-36fv-25j3-r2c5 for full advisory details.
Workarounds
- Add a custom ModSecurity rule that enforces a strict charset allow-list across every multipart segment using @rx against MULTIPART_PART_HEADERS without relying on chained capture variables.
- Reject multipart requests that contain mixed or conflicting charset declarations at the reverse proxy layer.
- Restrict accepted Content-Type values on upload endpoints to a narrow allow-list enforced by the application itself.
# Verify installed CRS version and upgrade
git -C /etc/modsecurity/coreruleset describe --tags
git -C /etc/modsecurity/coreruleset fetch --tags
git -C /etc/modsecurity/coreruleset checkout v4.22.0
systemctl reload nginx # or apache2, depending on deployment
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

