← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-33691 · CWE-178 · Disclosed 2026-04-02

The OWASP core rule set

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

Like a bouncer who checks the jacket but ignores the fake badge clipped on with extra tape

CVE-2026-33691 is a whitespace-normalization gap in OWASP CRS file-upload detection. In CRS versions earlier than 3.3.9 and 4.25.0, rules 933110, 933111, and in v4 also 944140, can miss dangerous upload names like photo. php or shell.jsp because the regex sees the space and fails to match the blocked extension. The vulnerable population is any app behind CRS that accepts file uploads and relies on these rules to catch executable extensions.

The vendor's MEDIUM 6.8 is reasonable as a lab score, but for enterprise patch triage it still overstates broad operational risk. This is a *defense bypass* in a rule set, not a direct server-side code execution bug: the attacker also needs a reachable upload feature, weak application-side validation, and a backend or hosting path that turns the whitespace-padded name into an executable file, which the advisory notes is especially practical on Windows and much less so on typical Linux deployments.

"This is a WAF filename-check bypass, not a direct compromise; real risk appears only on unsafe upload pipelines."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find an Internet-facing upload workflow

An attacker uses Burp Suite or ffuf to enumerate file-upload endpoints on an application sitting behind a CRS-backed WAF. The target must actually process user-supplied filenames through the affected CRS rules rather than bypassing them with custom exclusions or alternate ingress paths.
Conditions required:
  • Unauthenticated or low-friction access to an upload endpoint
  • Application traffic is inspected by OWASP CRS
  • Affected rules are enabled for the upload path
Where this breaks in practice:
  • Many enterprises do not expose arbitrary upload forms publicly
  • Some upload paths are authenticated or role-restricted
  • Custom WAF exclusions or alternate API gateways may mean the vulnerable rules are never in play
Detection/coverage: External scanners can infer upload functionality, but they cannot reliably prove this CVE without a safe test payload and response analysis.
STEP 02

Bypass the filename extension rule

Using curl or Burp Repeater, the attacker submits a multipart upload with a whitespace-padded filename such as photo. php or shell.jsp , matching the public GitHub advisory and regression-test examples. Because the rule only lowercases the filename and did not remove whitespace before regex evaluation, the dangerous extension check can miss.
Conditions required:
  • CRS version is earlier than 3.3.9 or 4.25.0
  • Target path uses rules 933110/933111 or 944140
  • The request reaches the WAF unchanged
Where this breaks in practice:
  • Some upstream components normalize or rewrite filenames before CRS sees them
  • Application-side validation may reject whitespace or rename the file
  • Custom local rule edits may already have added t:removeWhitespace
Detection/coverage: Version-based scanners may flag the package, but content inspection of the deployed rule files is more trustworthy because local backports are common.
STEP 03

Land an executable upload on the backend

The bypass only matters if the backend preserves attacker control over the uploaded file in a way that becomes executable later. The GitHub advisory explicitly calls out backends that strip or normalize whitespace from filenames, with Windows called out as the common case; on Linux, a file literally named . php is usually just a non-executable filename oddity unless the application trims it.
Conditions required:
  • Backend or application normalizes/strips whitespace from filenames, or otherwise maps the upload to an executable extension
  • Uploaded content is stored in a web-accessible or executable location
  • The application does not independently enforce safe extensions/MIME/type policy
Where this breaks in practice:
  • Most mature apps rename uploads to opaque IDs
  • Object storage or storage outside webroot breaks the chain
  • Many Linux stacks do not execute filenames containing the padded whitespace literally
Detection/coverage: DAST rarely proves the backend normalization step safely; this is usually confirmed by app review, controlled testing, or upload-storage inspection.
STEP 04

Trigger code execution or malicious file use

If the backend converts the padded filename into a live .php/.jsp resource, the attacker can call it with curl, a browser, or a simple web-shell client. At that point the impact stops being a WAF issue and becomes whatever the application host allows, from web-shell execution to integrity loss in a single app tier.
Conditions required:
  • Executable interpreter mapping exists for the landed file type
  • The file is reachable after upload
  • No downstream controls block execution
Where this breaks in practice:
  • Non-executable upload stores turn this into a harmless bypass with no code path
  • EDR, application allowlists, or hardened web-server mappings may stop the follow-on stage
  • Blast radius is usually limited to the specific app and upload path
Detection/coverage: Post-upload web-shell execution is more likely to be caught by EDR, web logs, or app telemetry than the original CRS bypass itself.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo evidence found of active exploitation campaigns. CISA KEV does not list CVE-2026-33691 as of this assessment.
Proof-of-concept availabilityPublic exploit guidance is effectively available in the vendor advisory and PRs: example payloads include photo. php, photo.php , test. php.jpg, and shell.jsp , plus regression tests in PRs #4546, #4547, and #4548.
EPSSUser-supplied EPSS is 0.00031 (~0.03% next-30-day exploitation probability). That is very low; an exact percentile was not retrieved from primary sources during this assessment.
KEV statusNot KEV-listed. No emergency override applies from KEV evidence.
CVSS baseline mismatchGitHub CNA: 6.8 MEDIUM with AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:H/A:N; NVD also publishes a higher 7.5 HIGH view. The gap comes from how much environment-dependent exploitation friction each scorer assumes.
Affected versions and rulesAffected versions are < 3.3.9 and < 4.25.0. The GitHub advisory names rules 933110 (PL1), 933111 (PL3), and 944140 (PL1), and states all paranoia levels up to PL4 are affected.
Fixed versionsPatched upstream in 3.3.9 and 4.25.0 by adding t:removeWhitespace. Debian shows modsecurity-crs fixed in 3.3.9-1 for sid/forky, while older Debian releases mark this as a minor issue rather than pushing a DSA.
Exposure realityThis is not a directly fingerprintable Internet service flaw. Exposure equals the subset of Internet-facing apps behind CRS that also offer file uploads and still depend on WAF-side filename blocking as a meaningful control.
Disclosure timelineReported to the project on 2026-03-10, GitHub advisory published 2026-03-28, NVD publication on 2026-04-02.
Reporter / remediationReported by @HackingRepo (KP3-260311); remediation work is credited to fzipi in the CRS project.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.7/10)

The decisive downgrading factor is that this is only a *WAF detection bypass* until the environment adds multiple extra weaknesses: an exposed upload path, no meaningful application-side validation, and backend filename normalization that turns the padded name into something executable. That sharply narrows both the reachable population and the real blast radius compared with a true pre-auth RCE or auth bypass in the app or server itself.

HIGH Exploit-chain friction is materially higher than the vendor CVSS alone suggests
MEDIUM Estate-wide exposure depends heavily on how many upload workflows still rely on CRS as a primary extension control

Why this verdict

  • Defense-bypass, not direct code execution: CRS fails to catch a bad filename pattern, but the attacker still needs the application and hosting stack to mishandle the uploaded file after the WAF lets it through.
  • Environment dependency cuts the population hard: the vendor advisory explicitly says practical exploitation is common on Windows-style whitespace normalization and much harder on Linux unless the application trims filenames itself.
  • Reachability is narrower than the CVSS baseline implies: only Internet-facing or attacker-reachable upload endpoints behind affected CRS versions are in scope, and many enterprise uploads are authenticated, renamed, stored outside webroot, or pushed to object storage.
  • Threat intel is cold: no KEV listing, no public campaign evidence, and the supplied EPSS 0.00031 is near the floor.

Why not higher?

This is not a one-request server takeover. The attacker must chain the CRS miss with a weak upload implementation and a backend that converts the padded filename into an executable or otherwise dangerous artifact, which is a lot of real-world friction.

Why not lower?

It is still remotely testable and requires no local foothold. In estates with legacy IIS/Windows upload handlers or sloppy filename normalization, this bypass can be the last step that turns an otherwise blocked web-shell upload into a real compromise.

05 · Compensating Control

What to do — in priority order.

  1. Rename uploads server-side — Force every upload to a random safe name and store the original filename only as metadata. This breaks the exploit chain regardless of CRS behavior; for a LOW verdict there is no fixed SLA date, so fold this into normal app-hardening work rather than emergency change control.
  2. Store uploads outside webroot — Make uploaded files non-executable by design and serve them indirectly through the application or object storage. That removes the main impact path entirely; for LOW, treat this as backlog hygiene in the next routine platform hardening cycle.
  3. Add local t:removeWhitespace to affected rules — If you cannot update CRS immediately, patch the local copies of rules 933110, 933111, and 944140 as the vendor advisory recommends. For LOW, there is no mitigation SLA, so do it in the next ordinary WAF policy maintenance window.
  4. Reject whitespace-padded executable names in the app — Application-side filename validation should reject suspicious patterns like spaces around dangerous extensions and should not trust multipart filename= values. For LOW, implement during normal developer backlog work, prioritizing any public upload workflow on Windows-backed apps.
What doesn't work
  • Raising CRS paranoia level doesn't help; the advisory says all paranoia levels up to PL4 are affected.
  • Relying on EDR alone is too late; EDR may catch web-shell execution, but it does not prevent the upload bypass itself.
  • MIME-type checks by themselves are weak if the app still permits executable storage paths or trusts client-supplied metadata.
06 · Verification

Crowdsourced verification payload.

Run this on the WAF or reverse-proxy host where CRS rule files are actually deployed, not from a scanner box. Invoke it as sudo bash check-cve-2026-33691.sh; root is recommended so it can read packaged rule locations under /etc, /usr/share, or /opt.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2026-33691.sh
# Detects whether deployed OWASP CRS rules for CVE-2026-33691 include t:removeWhitespace.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

SEARCH_DIRS=(
  "/etc/modsecurity"
  "/etc/crs4"
  "/usr/share/modsecurity-crs"
  "/usr/share/owasp-modsecurity-crs"
  "/opt/owasp-crs"
  "/opt/coreruleset"
)

found_dirs=()
for d in "${SEARCH_DIRS[@]}"; do
  if [ -d "$d" ]; then
    found_dirs+=("$d")
  fi
done

if [ ${#found_dirs[@]} -eq 0 ]; then
  echo "UNKNOWN - no common CRS directories found"
  exit 2
fi

find_rule_context() {
  local rule_id="$1"
  local hit file line start end
  while IFS= read -r hit; do
    file="${hit%%:*}"
    line_rest="${hit#*:}"
    line="${line_rest%%:*}"
    if [[ "$line" =~ ^[0-9]+$ ]]; then
      start=$(( line > 12 ? line - 12 : 1 ))
      end=$(( line + 25 ))
      sed -n "${start},${end}p" "$file"
      return 0
    fi
  done < <(grep -R -n -E "id:?${rule_id}([, ]|$)" "${found_dirs[@]}" 2>/dev/null)
  return 1
}

rule_status() {
  local rule_id="$1"
  local ctx
  if ! ctx="$(find_rule_context "$rule_id")"; then
    echo "NOTFOUND"
    return 0
  fi
  if grep -q "t:removeWhitespace" <<< "$ctx"; then
    echo "PATCHED"
  else
    echo "VULNERABLE"
  fi
}

r933110="$(rule_status 933110)"
r933111="$(rule_status 933111)"
r944140="$(rule_status 944140)"

# Need the PHP rules to make a determination.
if [ "$r933110" = "NOTFOUND" ] || [ "$r933111" = "NOTFOUND" ]; then
  echo "UNKNOWN - affected rule IDs 933110/933111 not found in deployed CRS content"
  exit 2
fi

# v4 installs normally include 944140; v3 does not.
if [ "$r944140" = "NOTFOUND" ]; then
  if [ "$r933110" = "PATCHED" ] && [ "$r933111" = "PATCHED" ]; then
    echo "PATCHED - v3-style rule set appears fixed (933110/933111 include t:removeWhitespace)"
    exit 0
  else
    echo "VULNERABLE - v3-style rule set missing t:removeWhitespace in 933110 and/or 933111"
    exit 1
  fi
else
  if [ "$r933110" = "PATCHED" ] && [ "$r933111" = "PATCHED" ] && [ "$r944140" = "PATCHED" ]; then
    echo "PATCHED - v4-style rule set appears fixed (933110/933111/944140 include t:removeWhitespace)"
    exit 0
  else
    echo "VULNERABLE - v4-style rule set missing t:removeWhitespace in one or more affected rules (933110/933111/944140)"
    exit 1
  fi
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do not treat this like an all-hands Internet-fire drill. Inventory public or partner-reachable apps with file uploads behind CRS, prioritize any Windows-backed or filename-trimming workflows, and then roll the CRS update or local rule fix into your next routine WAF content refresh; for a LOW verdict, the noisgate mitigation SLA does not apply and the noisgate remediation SLA also does not impose a hard date, so this is backlog hygiene unless your review shows CRS is the only thing stopping executable uploads on a real exposed app.

Sources

  1. GitHub Security Advisory GHSA-rw5f-9w43-gv2w
  2. NVD CVE-2026-33691
  3. OWASP CRS release v4.25.0
  4. OWASP CRS release v3.3.9
  5. PR #4546 fix(933110)
  6. PR #4548 fix(944140)
  7. Debian security tracker for CVE-2026-33691
  8. CISA Known Exploited Vulnerabilities Catalog
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.