ModSecurity defines 920120 with !@rx: its pattern describes a filename made only
of SAFE characters, and the rule fires when the filename does NOT match. A
quote, an apostrophe, a semicolon, an equals sign or a backslash in a filename
is an attempt to break out of the Content-Disposition header, and that is what
the rule exists to catch.
This format had no way to express a negation, so the rule was imported as a
plain pattern and means the exact opposite: it matched every legitimate upload
and missed every dangerous filename. It did no harm only because the engine
carried a built-in rule under the same ID — a different rule entirely, matching
content-type.*boundary.* on every ordinary multipart upload — which took
precedence.
The engine gained a `negate` field (3.0.61); this declares it. Both are needed:
the flag alone with no engine support does nothing, and engine support with no
flag leaves the rule inverted.
build_datetime bumped, because an agent skips a feed whose stamp has not moved
without reading it.
Rule 932180 "Restricted File Upload Attempt" targets filename, scores 10 and
blocks. Its pattern carries CRS's OS-pseudo-file list with no path anchor, so
bare words matched any uploaded filename:
module modules meminfo mounts misc mdstat mtrr loadavg locks version
uptime cmdline stat swaps slabinfo partitions pagetypeinfo
So release-version-2.zip, company-misc-notes.pdf and meminfo.txt were refused
as critical RCE attempts. Found because it blocked an image upload to our own
wiki, which sits behind EdgeGuard: the response carried x-edgeguard-id, the
console found the event by that id, and the match was `module-` in the
filename.
These names mean something as a PATH and nothing as a filename, so the branch
now requires a leading slash. The dotfile branch keeps its own (?:\b|^) anchor
and is untouched.
Measured against the previous pattern over a corpus of 51 names: 16 ordinary
filenames released, NOTHING newly blocked, and every true positive still
caught — .htaccess, .env, .aws/credentials, wp-config.php, /proc/version,
/proc/self/environ, ../../proc/modules, uploads/../../proc/kcore.
build_datetime bumped. An agent skips a feed whose stamp has not changed
without reading it, so a corrected pattern under the old stamp would reach
nobody.