ModSecurity
ModSecurity copied to clipboard
setvar never increments
Describe the bug
A clear and concise description of what the bug is.
setvar never increments:
# Initialize IP Collection
SecAction "id:9000000,\
phase:1,\
nolog,\
pass,\
initcol:ip=%{REMOTE_ADDR},\
setvar:ip.err_404_count=0,\
setvar:ip.err_403_count=0"
# Increment 404 Error Counter
SecRule RESPONSE_STATUS "^404$" "id:9000001,\
phase:3,\
nolog,\
pass,\
setvar:ip.err_404_count=+1"
# Log Updated 404 Error Counter
SecRule RESPONSE_STATUS "^404$" "id:9000002,\
phase:3,\
log,\
msg:'Incremented err_404_count for %{REMOTE_ADDR}. Current count: %{ip.err_404_count}',\
pass"
# Increment 403 Error Counter
SecRule RESPONSE_STATUS "^403$" "id:9000003,\
phase:3,\
nolog,\
pass,\
setvar:ip.err_403_count=+1"
# Log Updated 403 Error Counter
SecRule RESPONSE_STATUS "^403$" "id:9000004,\
phase:3,\
log,\
msg:'Incremented err_403_count for %{REMOTE_ADDR}. Current count: %{ip.err_403_count}',\
pass"
# Block IPs Exceeding Threshold for 404 Errors
SecRule ip:err_404_count "@gt 10" "id:9000005,\
phase:1,\
t:none,\
block,\
log,\
msg:'Blocking IP %{REMOTE_ADDR} after exceeding 404 error threshold. err_404_count: %{ip.err_404_count}',\
setvar:ip.err_404_count=0"
# Block IPs Exceeding Threshold for 403 Errors
SecRule ip:err_403_count "@gt 10" "id:9000006,\
phase:1,\
t:none,\
block,\
log,\
msg:'Blocking IP %{REMOTE_ADDR} after exceeding 403 error threshold. err_403_count: %{ip.err_403_count}',\
setvar:ip.err_403_count=0"
# Set Expiration for IP Collection Variables
SecAction "id:9000007,\
phase:1,\
nolog,\
pass,\
expirevar:ip.err_404_count=3600,\
expirevar:ip.err_403_count=3600"
Logs and dumps
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [4] (Rule: 9000000) Executing unconditional rule...
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [4] Running [independent] (non-disruptive) action: setvar
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [8] Saving variable: IP:err_404_count with value: 0
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [4] Running [independent] (non-disruptive) action: setvar
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [8] Saving variable: IP:err_403_count with value: 0
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Running action: log
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Saving transaction to logs
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Running action: auditlog
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Saving transaction to logs
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Running action: nolog
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Running action: initcol
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [5] Collection `ip' initialized with value: xxx.xxx.xx.xx
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [4] Running (disruptive) action: pass.
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [8] Running action pass
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [4] (Rule: 9000005) Executing operator "Gt" with param "10" against IP:err_404_count.
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [4] Rule returned 0.
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Matched vars cleaned.
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [4] (Rule: 9000006) Executing operator "Gt" with param "10" against IP:err_403_count.
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [4] Rule returned 0.
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Matched vars cleaned.
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [4] (Rule: 9000007) Executing unconditional rule...
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Running action: log
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Saving transaction to logs
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Running action: auditlog
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Saving transaction to logs
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Running action: nolog
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Running action: expirevar
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Setting variable `err_404_count' to expire in 3600 seconds.
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Running action: expirevar
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [9] Setting variable `err_403_count' to expire in 3600 seconds.
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [4] Running (disruptive) action: pass.
[2162f9f7aa356f41b76c3c5e3ca1a377] [/bill] [8] Running action pass
Output of:
- DebugLogs (level 9)
To Reproduce
- Add the above rules.
- watch -n 1 curl -s -o /dev/null -w "%{http_code}" https://yourwebsite.com/some404url
- No blocking action takes place.
Steps to reproduce the behavior:
watch -n 1 curl -s -o /dev/null -w "%{http_code}" https://yourwebsite.com/some404url
Expected behavior
A clear and concise description of what you expected to happen. Must block with 403 and log:
Blocking IP %{REMOTE_ADDR} after exceeding 403 error threshold. err_403_count: %{ip.err_403_count}
Server (please complete the following information): LibModsecurity: https://github.com/owasp-modsecurity/ModSecurity/commit/99ce9779e69dd7364396d959f7edd9729ef56596 Nginx Connector: https://github.com/owasp-modsecurity/ModSecurity-nginx/commit/ef64996aedd4bb5fa1831631361244813d48b82f Nginx: Stock Debian package
nginx -V
nginx version: nginx/1.24.0
built with OpenSSL 3.1.4 24 Oct 2023 (running with OpenSSL 3.3.1 4 Jun 2024)
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -ffile-prefix-map=/build/reproducible-path/nginx-1.24.0=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=stderr --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-compat --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_secure_link_module --with-http_sub_module --with-mail_ssl_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-stream_realip_module --with-http_geoip_module=dynamic --with-http_image_filter_module=dynamic --with-http_perl_module=dynamic --with-http_xslt_module=dynamic --with-mail=dynamic --with-stream=dynamic --with-stream_geoip_module=dynamic
LibModSecurity:
ldd /usr/local/modsecurity/lib/libmodsecurity.so
linux-vdso.so.1 (0x00007ffcbe5a7000)
libcurl.so.4 => /lib/x86_64-linux-gnu/libcurl.so.4 (0x00007f051297f000)
libGeoIP.so.1 => /lib/x86_64-linux-gnu/libGeoIP.so.1 (0x00007f0512941000)
libxml2.so.2 => /lib/x86_64-linux-gnu/libxml2.so.2 (0x00007f051244e000)
liblmdb.so.0 => /lib/x86_64-linux-gnu/liblmdb.so.0 (0x00007f051292a000)
liblua5.3.so.0 => /lib/x86_64-linux-gnu/liblua5.3.so.0 (0x00007f05128ee000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f05123b3000)
libmaxminddb.so.0 => /lib/x86_64-linux-gnu/libmaxminddb.so.0 (0x00007f05128e5000)
libfuzzy.so.2 => /lib/x86_64-linux-gnu/libfuzzy.so.2 (0x00007f05128de000)
libyajl.so.2 => /lib/x86_64-linux-gnu/libyajl.so.2 (0x00007f05128d2000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0512000000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0511e16000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0512a62000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f05128a3000)
libnghttp2.so.14 => /lib/x86_64-linux-gnu/libnghttp2.so.14 (0x00007f0512872000)
libidn2.so.0 => /lib/x86_64-linux-gnu/libidn2.so.0 (0x00007f0512380000)
librtmp.so.1 => /lib/x86_64-linux-gnu/librtmp.so.1 (0x00007f0512362000)
libssh2.so.1 => /lib/x86_64-linux-gnu/libssh2.so.1 (0x00007f051231b000)
libpsl.so.5 => /lib/x86_64-linux-gnu/libpsl.so.5 (0x00007f0512307000)
libssl.so.3 => /lib/x86_64-linux-gnu/libssl.so.3 (0x00007f0511d13000)
libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x00007f0511600000)
libgssapi_krb5.so.2 => /lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007f05122b4000)
libldap-2.5.so.0 => /lib/x86_64-linux-gnu/libldap-2.5.so.0 (0x00007f0511cb3000)
liblber-2.5.so.0 => /lib/x86_64-linux-gnu/liblber-2.5.so.0 (0x00007f05122a4000)
libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007f0511bf2000)
libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007f0512296000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f0512277000)
libicuuc.so.72 => /lib/x86_64-linux-gnu/libicuuc.so.72 (0x00007f0511200000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f0511bc2000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f051151e000)
libunistring.so.5 => /lib/x86_64-linux-gnu/libunistring.so.5 (0x00007f0511050000)
libgnutls.so.30 => /lib/x86_64-linux-gnu/libgnutls.so.30 (0x00007f0510e00000)
libhogweed.so.6 => /lib/x86_64-linux-gnu/libhogweed.so.6 (0x00007f05114d4000)
libnettle.so.8 => /lib/x86_64-linux-gnu/libnettle.so.8 (0x00007f0511480000)
libgmp.so.10 => /lib/x86_64-linux-gnu/libgmp.so.10 (0x00007f0510d78000)
libkrb5.so.3 => /lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007f0510c9c000)
libk5crypto.so.3 => /lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007f0511b95000)
libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007f0512271000)
libkrb5support.so.0 => /lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007f0511b87000)
libsasl2.so.2 => /lib/x86_64-linux-gnu/libsasl2.so.2 (0x00007f0511464000)
libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007f0511441000)
libicudata.so.72 => /lib/x86_64-linux-gnu/libicudata.so.72 (0x00007f050ee00000)
libp11-kit.so.0 => /lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007f050ec61000)
libtasn1.so.6 => /lib/x86_64-linux-gnu/libtasn1.so.6 (0x00007f051142b000)
libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007f0512268000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f051141a000)
libffi.so.8 => /lib/x86_64-linux-gnu/libffi.so.8 (0x00007f051140d000)
Nginx Libmodsecurity Connector:
ldd /usr/lib/nginx/modules/ngx_http_modsecurity_module.so
linux-vdso.so.1 (0x00007ffea8712000)
libmodsecurity.so.3 => /usr/local/modsecurity/lib/libmodsecurity.so.3 (0x00007f7da0400000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7da0216000)
libcurl.so.4 => /lib/x86_64-linux-gnu/libcurl.so.4 (0x00007f7da06d8000)
libGeoIP.so.1 => /lib/x86_64-linux-gnu/libGeoIP.so.1 (0x00007f7da069a000)
libxml2.so.2 => /lib/x86_64-linux-gnu/libxml2.so.2 (0x00007f7da0064000)
liblmdb.so.0 => /lib/x86_64-linux-gnu/liblmdb.so.0 (0x00007f7da0681000)
liblua5.3.so.0 => /lib/x86_64-linux-gnu/liblua5.3.so.0 (0x00007f7da0028000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f7d9ff8d000)
libmaxminddb.so.0 => /lib/x86_64-linux-gnu/libmaxminddb.so.0 (0x00007f7da067a000)
libfuzzy.so.2 => /lib/x86_64-linux-gnu/libfuzzy.so.2 (0x00007f7da0673000)
libyajl.so.2 => /lib/x86_64-linux-gnu/libyajl.so.2 (0x00007f7d9ff81000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f7d9fc00000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7da07c2000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7d9ff54000)
libnghttp2.so.14 => /lib/x86_64-linux-gnu/libnghttp2.so.14 (0x00007f7d9ff23000)
libidn2.so.0 => /lib/x86_64-linux-gnu/libidn2.so.0 (0x00007f7d9fef0000)
librtmp.so.1 => /lib/x86_64-linux-gnu/librtmp.so.1 (0x00007f7d9fed2000)
libssh2.so.1 => /lib/x86_64-linux-gnu/libssh2.so.1 (0x00007f7d9fe8b000)
libpsl.so.5 => /lib/x86_64-linux-gnu/libpsl.so.5 (0x00007f7d9fe77000)
libssl.so.3 => /lib/x86_64-linux-gnu/libssl.so.3 (0x00007f7d9fafd000)
libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x00007f7d9f400000)
libgssapi_krb5.so.2 => /lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007f7d9faaa000)
libldap-2.5.so.0 => /lib/x86_64-linux-gnu/libldap-2.5.so.0 (0x00007f7d9fa4a000)
liblber-2.5.so.0 => /lib/x86_64-linux-gnu/liblber-2.5.so.0 (0x00007f7d9fe67000)
libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007f7d9f989000)
libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007f7d9f3f2000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f7d9f3d3000)
libicuuc.so.72 => /lib/x86_64-linux-gnu/libicuuc.so.72 (0x00007f7d9f000000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f7d9f3a3000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7d9f2c1000)
libunistring.so.5 => /lib/x86_64-linux-gnu/libunistring.so.5 (0x00007f7d9ee50000)
libgnutls.so.30 => /lib/x86_64-linux-gnu/libgnutls.so.30 (0x00007f7d9ec00000)
libhogweed.so.6 => /lib/x86_64-linux-gnu/libhogweed.so.6 (0x00007f7d9f277000)
libnettle.so.8 => /lib/x86_64-linux-gnu/libnettle.so.8 (0x00007f7d9f223000)
libgmp.so.10 => /lib/x86_64-linux-gnu/libgmp.so.10 (0x00007f7d9eb78000)
libkrb5.so.3 => /lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007f7d9ea9c000)
libk5crypto.so.3 => /lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007f7d9ee23000)
libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007f7d9f21d000)
libkrb5support.so.0 => /lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007f7d9f20f000)
libsasl2.so.2 => /lib/x86_64-linux-gnu/libsasl2.so.2 (0x00007f7d9ea80000)
libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007f7d9ea5d000)
libicudata.so.72 => /lib/x86_64-linux-gnu/libicudata.so.72 (0x00007f7d9cc00000)
libp11-kit.so.0 => /lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007f7d9ca61000)
libtasn1.so.6 => /lib/x86_64-linux-gnu/libtasn1.so.6 (0x00007f7d9ea47000)
libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007f7d9f208000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f7d9ea36000)
libffi.so.8 => /lib/x86_64-linux-gnu/libffi.so.8 (0x00007f7d9ea29000)
Rule Set (please complete the following information): Coreruleset: tx.crs_setup_version=400
Hi @sharmashivanand,
your first rule is an unconditional SecRule (a SecAction):
# Initialize IP Collection
SecAction "id:9000000,\
phase:1,\
nolog,\
pass,\
initcol:ip=%{REMOTE_ADDR},\
setvar:ip.err_404_count=0,\
setvar:ip.err_403_count=0"
It means this rule always executed and you always set the ip.err_404_count and ip.err_403_count to 0. Therefore, if you increase this value in vain, it will be 0 again when a new transaction starts.
You should figure out what condition could solve this in your case and modify the first rule not to set 0 that counters in all transactions.