Description
coreruleset (aka OWASP ModSecurity Core Rule Set) through 3.3.4 does not detect multiple Content-Type request headers on some platforms. This might allow attackers to bypass a WAF with a crafted payload, aka "Content-Type confusion" between the WAF and the backend application. This occurs when the web application relies on only the last Content-Type header. Other platforms may reject the additional Content-Type header or merge conflicting headers, leading to detection as a malformed header.
EPSS Score:
0%
EUVD-2023-42021: Technical Security Analysis
OWASP ModSecurity Core Rule Set Content-Type Confusion Vulnerability
1. VULNERABILITY ASSESSMENT AND SEVERITY EVALUATION
Severity Classification
CVSS v3.1 Base Score: 9.8 (CRITICAL)
The CVSS vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H indicates:
- Attack Vector (AV:N): Network-exploitable, requiring no physical or local access
- Attack Complexity (AC:L): Low complexity; no specialized conditions required
- Privileges Required (PR:N): No authentication or privileges needed
- User Interaction (UI:N): No user interaction required for exploitation
- Scope (S:U): Unchanged; impact limited to vulnerable component
- Confidentiality/Integrity/Availability (C:H/I:H/A:H): High impact across all three security pillars
Technical Assessment
This vulnerability represents a critical HTTP request smuggling/header manipulation flaw that exploits inconsistent header parsing behavior between Web Application Firewalls (WAFs) and backend application servers. The vulnerability allows attackers to bypass security controls through Content-Type header confusion, potentially leading to:
- Complete WAF bypass
- Injection attacks (SQL, XSS, XXE, etc.)
- Authentication/authorization bypass
- Remote code execution (depending on backend vulnerabilities)
- Data exfiltration
The critical severity is justified given the fundamental security control bypass nature and the widespread deployment of OWASP ModSecurity CRS as a primary defense mechanism.
2. POTENTIAL ATTACK VECTORS AND EXPLOITATION METHODS
Attack Mechanism
The vulnerability exploits differential header parsing between the WAF and backend application:
POST /api/endpoint HTTP/1.1
Host: target.example.com
Content-Type: application/json
Content-Type: application/x-www-form-urlencoded
Content-Length: 150
{"legitimate":"data"}
Exploitation Scenarios
Scenario A: WAF Bypass for Injection Attacks
POST /search HTTP/1.1
Host: vulnerable-app.eu
Content-Type: application/json
Content-Type: text/plain
username=admin' OR '1'='1&password=bypass
Exploitation Flow:
- WAF inspects first
Content-Type: application/jsonheader - WAF applies JSON-specific rules, expects JSON payload
- Malformed JSON doesn't trigger SQL injection signatures
- Backend application processes last Content-Type header
- Backend parses payload as form data, executing SQL injection
Scenario B: XML External Entity (XXE) Injection
POST /upload HTTP/1.1
Host: api.target.eu
Content-Type: multipart/form-data
Content-Type: application/xml
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<data>&xxe;</data>
Scenario C: Deserialization Attack Bypass
POST /api/process HTTP/1.1
Host: backend.example.eu
Content-Type: application/json
Content-Type: application/x-java-serialized-object
[serialized malicious object payload]
Platform-Specific Behavior
Vulnerable Platforms (process last header):
- Apache HTTP Server (certain configurations)
- Nginx (specific module combinations)
- Node.js/Express (default behavior)
- Python Flask/Django (depending on middleware)
Resistant Platforms (reject or merge):
- IIS (rejects duplicate headers)
- Some Java servlet containers (merge with comma separation)
- HAProxy (configurable, may reject)
3. AFFECTED SYSTEMS AND SOFTWARE VERSIONS
Directly Affected Software
- OWASP ModSecurity Core Rule Set (CRS): Versions ≤ 3.3.4
- All 3.x versions up to and including 3.3.4
- Potentially earlier 2.x versions (unconfirmed)
Deployment Contexts at Risk
Web Application Firewalls
- ModSecurity with CRS (standalone)
- Commercial WAF solutions incorporating CRS rules
- Cloud WAF services using CRS as baseline
Web Servers and Reverse Proxies
- Apache HTTP Server with mod_security2
- Nginx with ModSecurity connector
- IIS with ModSecurity module
- Reverse proxy configurations (Nginx, HAProxy, Traefik)
Application Platforms
Backend applications vulnerable when combined with affected CRS versions:
- RESTful APIs (JSON/XML endpoints)
- Legacy SOAP services
- Content Management Systems (WordPress, Drupal, Joomla)
- E-commerce platforms (Magento, WooCommerce)
- Custom web applications with file upload functionality
- Microservices architectures
European Critical Infrastructure Exposure
Given CRS's widespread adoption, affected sectors include:
- Financial services (PSD2-compliant payment gateways)
- Healthcare (GDPR-protected patient portals)
- Government services (e-Government platforms)
- Telecommunications
- Energy sector SCADA web interfaces
4. RECOMMENDED MITIGATION STRATEGIES
Immediate Actions (Priority 1 - Within 24-48 Hours)
A. Update Core Rule Set
# Verify current version
grep -i "SecComponentSignature" /etc/modsecurity/crs-setup.conf
# Update to patched version (≥ 3.3.5)
cd /opt/coreruleset
git fetch --tags
git checkout v3.3.5 # or latest stable
systemctl restart apache2 # or nginx
B. Implement Emergency Rule
Add custom ModSecurity rule to detect duplicate Content-Type headers:
# File: /etc/modsecurity/custom-rules/duplicate-content-type.conf
SecRule REQUEST_HEADERS:Content-Type "@rx ^(.+)$" \
"id:999001,\
phase:1,\
t:none,\
capture,\
chain,\
log,\
deny,\
status:400,\
msg:'Multiple Content-Type headers detected'"
SecRule REQUEST_HEADERS:Content-Type "!@streq %{TX.1}" \
"t:none"
C. Web Server Configuration Hardening
Apache HTTP Server:
# Reject requests with duplicate headers
<IfModule mod_headers.c>
RequestHeader unset Content-Type env=DUPLICATE_CONTENT_TYPE
SetEnvIf Content-Type "^(.*)$" FIRST_CT=$1
SetEnvIf Content-Type "^(.*)$" DUPLICATE_CONTENT_TYPE
SetEnvIf Content-Type "^%{FIRST_CT}$" !DUPLICATE_CONTENT_TYPE
</IfModule>
Nginx:
# Reject duplicate Content-Type headers
map $http_content_type $content_type_count {
default 0;
~^(.+),(.+)$ 1;
}
server {
if ($content_type_count = 1) {
return 400 "Duplicate headers not allowed";
}
}
Medium-Term Actions (Priority 2 - Within 1 Week)
D. Application-Level Validation
Implement strict header validation in application code:
# Python/Flask example
from flask import request, abort
@app.before_request
def validate_headers():
content_types = request.headers.getlist('Content-Type')
if len(content_types) > 1:
abort(400, "Multiple Content-Type headers detected")
// Node.js/Express example
app.use((req, res, next) => {
const contentTypes = req.rawHeaders.filter(
(header, index) => index % 2 === 0 &&
header.toLowerCase() === 'content-type'
);
if (contentTypes.length > 1) {