ModSecurity icon indicating copy to clipboard operation
ModSecurity copied to clipboard

setvar never increments

Open sharmashivanand opened this issue 1 year ago • 1 comments

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:

  1. DebugLogs (level 9)

To Reproduce

  1. Add the above rules.
  2. watch -n 1 curl -s -o /dev/null -w "%{http_code}" https://yourwebsite.com/some404url
  3. 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

sharmashivanand avatar Oct 15 '24 16:10 sharmashivanand

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.

airween avatar Oct 18 '24 14:10 airween