CVE-2023-45132 (published 2023-10-11T21:15Z)

NAXSI is an open-source maintenance web application firewall (WAF) for NGINX. An issue present starting in version 1.3 and prior to version 1.6 allows someone to bypass the WAF when a malicious `X-Forwarded-For` IP matches `IgnoreIP` `IgnoreCIDR` rules. This old code was arranged to allow older NGINX versions to also support `IgnoreIP` `IgnoreCIDR` when multiple reverse proxies were present. The issue is patched in version 1.6. As a workaround, do not set any `IgnoreIP` `IgnoreCIDR` for older versions.\n

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/wargio/naxsi
commit_details: repo_url: https://github.com/wargio/naxsi
author: lubomudr
author_date: 2023-10-09 16:20:20+10:00
msg: Remove X-Forwarded-For header special processing (#103)

* Change tests IgnoreCIDR/IgnoreIP with/without real_ip support
* Remove X-Forwarding-For header special processing
* Change tests IgnoreCIDR/IgnoreIP set_real_ip_from 127.0.0.1 for IPv6 (for IPv4 machine only)
* Change tests IgnoreCIDR/IgnoreIP set_real_ip_from 127.0.0.1 and ::1/128 for IPv6
repository: repo_url: https://github.com/wargio/naxsi
repo_name: wargio/naxsi
description: NAXSI is an open-source, high performance, low rules maintenance WAF for NGINX
repo_language: C
owner: wargio
file_changes: filename: ci-build.sh
change_type: ModificationType.MODIFY
diff: @@ -49,6 +49,7 @@ if $NEW_BUILD ; then
                 --without-mail_pop3_module \
                 --without-mail_smtp_module \
                 --without-mail_imap_module \
+                --with-http_realip_module \
                 --with-http_v2_module \
                 --without-http_uwsgi_module \
                 --without-http_scgi_module \

programming_language: Shell
filename: naxsi_runtime.c
change_type: ModificationType.MODIFY
diff: @@ -2912,36 +2912,6 @@ ngx_http_naxsi_update_current_ctx_status(ngx_http_request_ctx_t*    ctx,
   NX_DEBUG(_debug_custom_score, NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "XX-custom check rules");
 
   if (!ctx->ignore && (cf->ignore_ips || cf->ignore_cidrs)) {
-#if (NGX_HTTP_X_FORWARDED_FOR)
-#if (nginx_version < 1023000)
-    ngx_table_elt_t** h;
-    if (r->headers_in.x_forwarded_for.nelts >= 1) {
-      h = r->headers_in.x_forwarded_for.elts;
-      NX_DEBUG(_debug_whitelist_ignore,
-               NGX_LOG_DEBUG_HTTP,
-               r->connection->log,
-               0,
-               "XX- lookup ignore X-Forwarded-For: %V",
-               h[0]->value);
-      ngx_str_t* ip = &h[0]->value;
-      ctx->ignore   = naxsi_can_ignore_ip(ip, cf) || naxsi_can_ignore_cidr(ip, cf);
-    } else
-#else
-    ngx_table_elt_t* xff;
-    if (r->headers_in.x_forwarded_for != NULL) {
-      xff = r->headers_in.x_forwarded_for;
-      NX_DEBUG(_debug_whitelist_ignore,
-               NGX_LOG_DEBUG_HTTP,
-               r->connection->log,
-               0,
-               "XX- lookup ignore X-Forwarded-For: %V",
-               xff->value);
-      ngx_str_t* ip = &xff->value;
-      ctx->ignore   = naxsi_can_ignore_ip(ip, cf) || naxsi_can_ignore_cidr(ip, cf);
-    } else
-#endif
-#endif
-    {
       ngx_str_t* ip = &r->connection->addr_text;
       NX_DEBUG(_debug_whitelist_ignore,
                NGX_LOG_DEBUG_HTTP,
@@ -2950,7 +2920,6 @@ ngx_http_naxsi_update_current_ctx_status(ngx_http_request_ctx_t*    ctx,
                "XX- lookup ignore client ip: %V",
                ip);
       ctx->ignore = naxsi_can_ignore_ip(ip, cf) || naxsi_can_ignore_cidr(ip, cf);
-    }
   }
 
   if (cf->check_rules && ctx->special_scores) {

programming_language: C
filename: 33ignoreip.t
change_type: ModificationType.MODIFY
diff: @@ -60,7 +60,7 @@ location /RequestDenied {
 GET /?a=buibui
 --- error_code: 200
 
-=== TEST 1.2: IgnoreIP request with X-Forwarded-For allow (ipv4) 
+=== TEST 1.2.1: IgnoreIP request with X-Forwarded-For allow without real_ip config (ipv4) 
 --- main_config
 load_module $TEST_NGINX_NAXSI_MODULE_SO;
 --- http_config
@@ -83,10 +83,38 @@ location /RequestDenied {
 --- more_headers
 X-Forwarded-For: 1.1.1.1
 --- request
-GET /?a=buibui
+GET /?a=<>
+--- error_code: 412
+
+=== TEST 1.2.2: IgnoreIP request with X-Forwarded-For allow with real_ip config (ipv4) 
+--- main_config
+load_module $TEST_NGINX_NAXSI_MODULE_SO;
+--- http_config
+include $TEST_NGINX_NAXSI_RULES;
+set_real_ip_from 127.0.0.1;
+real_ip_header X-Forwarded-For;
+--- config
+location / {
+     SecRulesEnabled;
+     IgnoreIP  "1.1.1.1";
+     DeniedUrl "/RequestDenied";
+     CheckRule "$SQL >= 8" BLOCK;
+     CheckRule "$RFI >= 8" BLOCK;
+     CheckRule "$TRAVERSAL >= 4" BLOCK;
+     CheckRule "$XSS >= 8" BLOCK;
+     root $TEST_NGINX_SERVROOT/html/;
+     index index.html index.htm;
+}
+location /RequestDenied {
+     return 412;
+}
+--- more_headers
+X-Forwarded-For: 1.1.1.1
+--- request
+GET /?a=<>
 --- error_code: 200
 
-=== TEST 1.3: IgnoreIP request with X-Forwarded-For allow (ipv6)
+=== TEST 1.3.1: IgnoreIP request with X-Forwarded-For allow without reaL_ip config (ipv6)
 --- main_config
 load_module $TEST_NGINX_NAXSI_MODULE_SO;
 --- http_config
@@ -109,7 +137,36 @@ location /RequestDenied {
 --- more_headers
 X-Forwarded-For: 2001:4860:4860::8844
 --- request
-GET /?a=buibui
+GET /?a=<>
+--- error_code: 412
+
+=== TEST 1.3.2: IgnoreIP request with X-Forwarded-For allow with real_ip config (ipv6)
+--- main_config
+load_module $TEST_NGINX_NAXSI_MODULE_SO;
+--- http_config
+include $TEST_NGINX_NAXSI_RULES;
+set_real_ip_from 127.0.0.1;
+set_real_ip_from ::1/128;
+real_ip_header X-Forwarded-For;
+--- config
+location / {
+     SecRulesEnabled;
+     IgnoreIP "2001:4860:4860::8844";
+     DeniedUrl "/RequestDenied";
+     CheckRule "$SQL >= 8" BLOCK;
+     CheckRule "$RFI >= 8" BLOCK;
+     CheckRule "$TRAVERSAL >= 4" BLOCK;
+     CheckRule "$XSS >= 8" BLOCK;
+     root $TEST_NGINX_SERVROOT/html/;
+     index index.html index.htm;
+}
+location /RequestDenied {
+     return 412;
+}
+--- more_headers
+X-Forwarded-For: 2001:4860:4860::8844
+--- request
+GET /?a=<>
 --- error_code: 200
 
 === TEST 1.4: IgnoreIP request with X-Forwarded-For deny (ipv4)

programming_language: C++
filename: 34ignorecidr.t
change_type: ModificationType.MODIFY
diff: @@ -60,7 +60,7 @@ location /RequestDenied {
 GET /?a=buibui
 --- error_code: 200
 
-=== TEST 1.2: IgnoreCIDR request with X-Forwarded-For allow (no file) 
+=== TEST 1.2.1: IgnoreCIDR request with X-Forwarded-For allow without real_ip config (no file)
 --- main_config
 load_module $TEST_NGINX_NAXSI_MODULE_SO;
 --- http_config
@@ -83,7 +83,35 @@ location /RequestDenied {
 --- more_headers
 X-Forwarded-For: 1.1.1.1
 --- request
-GET /?a=buibui
+GET /?a=<>
+--- error_code: 412
+
+=== TEST 1.2.2: IgnoreCIDR request with X-Forwarded-For allow with real_ip config (no file)
+--- main_config
+load_module $TEST_NGINX_NAXSI_MODULE_SO;
+--- http_config
+include $TEST_NGINX_NAXSI_RULES;
+set_real_ip_from 127.0.0.1;
+real_ip_header X-Forwarded-For;
+--- config
+location / {
+     SecRulesEnabled;
+     IgnoreCIDR "1.1.1.0/24";
+     DeniedUrl "/RequestDenied";
+     CheckRule "$SQL >= 8" BLOCK;
+     CheckRule "$RFI >= 8" BLOCK;
+     CheckRule "$TRAVERSAL >= 4" BLOCK;
+     CheckRule "$XSS >= 8" BLOCK;
+     root $TEST_NGINX_SERVROOT/html/;
+         index index.html index.htm;
+}
+location /RequestDenied {
+     return 412;
+}
+--- more_headers
+X-Forwarded-For: 1.1.1.1
+--- request
+GET /?a=<>
 --- error_code: 200
 
 === TEST 1.3: IgnoreCIDR request with X-Forwarded-For deny (no file)
@@ -163,7 +191,7 @@ location /RequestDenied {
 GET /foobar
 --- error_code: 200
 
-=== TEST 1.6: IgnoreCIDR request with X-Forwarded-For allow (ipv6)
+=== TEST 1.6.1: IgnoreCIDR request with X-Forwarded-For allow without real_ip config (ipv6)
 --- main_config
 load_module $TEST_NGINX_NAXSI_MODULE_SO;
 --- http_config
@@ -187,13 +215,71 @@ location /RequestDenied {
 X-Forwarded-For: 2001:4860:4860::8888
 --- request
 GET /?a=<>
+--- error_code: 412
+
+=== TEST 1.6.2: IgnoreCIDR request with X-Forwarded-For allow with real_ip config (ipv6)
+--- main_config
+load_module $TEST_NGINX_NAXSI_MODULE_SO;
+--- http_config
+include $TEST_NGINX_NAXSI_RULES;
+set_real_ip_from 127.0.0.1;
+set_real_ip_from ::1/128;
+real_ip_header X-Forwarded-For;
+--- config
+location / {
+     SecRulesEnabled;
+     IgnoreCIDR "2001:4860:4860::/112";
+     DeniedUrl "/RequestDenied";
+     CheckRule "$SQL >= 8" BLOCK;
+     CheckRule "$RFI >= 8" BLOCK;
+     CheckRule "$TRAVERSAL >= 4" BLOCK;
+     CheckRule "$XSS >= 8" BLOCK;
+     root $TEST_NGINX_SERVROOT/html/;
+     index index.html index.htm;
+}
+location /RequestDenied {
+     return 412;
+}
+--- more_headers
+X-Forwarded-For: 2001:4860:4860::8888
+--- request
+GET /?a=<>
 --- error_code: 200
 
-=== TEST 1.7: Verify IgnoreCIDR 2001:4860:4860::8888/128 is converted to IgnoreIP
+=== TEST 1.7.1: Verify IgnoreCIDR 2001:4860:4860::8888/128 is converted to IgnoreIP without real_ip config
+--- main_config
+load_module $TEST_NGINX_NAXSI_MODULE_SO;
+--- http_config
+include $TEST_NGINX_NAXSI_RULES;
+--- config
+location / {
+     SecRulesEnabled;
+     IgnoreCIDR "2001:4860:4860::8888/128";
+     DeniedUrl "/RequestDenied";
+     CheckRule "$SQL >= 8" BLOCK;
+     CheckRule "$RFI >= 8" BLOCK;
+     CheckRule "$TRAVERSAL >= 4" BLOCK;
+     CheckRule "$XSS >= 8" BLOCK;
+     root $TEST_NGINX_SERVROOT/html/;
+     index index.html index.htm;
+}
+location /RequestDenied {
+     return 412;
+}
+--- more_headers
+X-Forwarded-For: 2001:4860:4860::8888
+--- request
+GET /?a=<>
+--- error_code: 412
+
+=== TEST 1.7.2: Verify IgnoreCIDR 2001:4860:4860::8888/128 is converted to IgnoreIP with real_ip config
 --- main_config
 load_module $TEST_NGINX_NAXSI_MODULE_SO;
 --- http_config
 include $TEST_NGINX_NAXSI_RULES;
+set_real_ip_from 127.0.0.1;
+set_real_ip_from ::1/128;
+real_ip_header X-Forwarded-For;
 --- config
 location / {
      SecRulesEnabled;

programming_language: C++