CVE-2023-45132: Insufficient Information (NVD-CWE-noinfo)
value: 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.

CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 9.8
Published: 2023-10-11T21:15Z
Repository: https://github.com/wargio/naxsi
Language: Other
Files changed: .scripts/ci-build.sh, naxsi_src/naxsi_runtime.c, unit-tests/tests/33ignoreip.t, unit-tests/tests/34ignorecidr.t
Commit date: 2023-10-09 08:20:20 +0200
Commit message: 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
Diff: diff --git a/.scripts/ci-build.sh b/.scripts/ci-build.sh
index 87ce662..a377a96 100755
--- a/.scripts/ci-build.sh
+++ b/.scripts/ci-build.sh
@@ -47,10 +47,11 @@ if $NEW_BUILD ; then
                 --pid-path="$NAXSI_TMP_PATH/naxsi_ut/nginx.pid" \
                 --modules-path="$NAXSI_TMP_PATH/naxsi_ut/modules/" \
                 --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 \
                 --prefix="$NAXSI_TMP_PATH/" \
                 --add-dynamic-module="$NAXSI_SRC_PATH" \
diff --git a/naxsi_src/naxsi_runtime.c b/naxsi_src/naxsi_runtime.c
index 7f30255..b8de9b4 100644
--- a/naxsi_src/naxsi_runtime.c
+++ b/naxsi_src/naxsi_runtime.c
@@ -2910,49 +2910,18 @@ ngx_http_naxsi_update_current_ctx_status(ngx_http_request_ctx_t*    ctx,
   ngx_http_special_score_t* sc;
 
   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,
                r->connection->log,
                0,
                "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) {
     NX_DEBUG(_debug_custom_score,
              NGX_LOG_DEBUG_HTTP,
diff --git a/unit-tests/tests/33ignoreip.t b/unit-tests/tests/33ignoreip.t
index be02664..1b823bf 100644
--- a/unit-tests/tests/33ignoreip.t
+++ b/unit-tests/tests/33ignoreip.t
@@ -58,11 +58,11 @@ location /RequestDenied {
 }
 --- request
 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
 include $TEST_NGINX_NAXSI_RULES;
 --- config
@@ -81,14 +81,42 @@ location /RequestDenied {
      return 412;
 }
 --- 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
 include $TEST_NGINX_NAXSI_RULES;
 --- config
@@ -107,11 +135,40 @@ location /RequestDenied {
      return 412;
 }
 --- 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)
 --- main_config
 load_module $TEST_NGINX_NAXSI_MODULE_SO;
diff --git a/unit-tests/tests/34ignorecidr.t b/unit-tests/tests/34ignorecidr.t
index f677d7d..bbccecd 100644
--- a/unit-tests/tests/34ignorecidr.t
+++ b/unit-tests/tests/34ignorecidr.t
@@ -58,11 +58,11 @@ location /RequestDenied {
 }
 --- request
 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
 include $TEST_NGINX_NAXSI_RULES;
 --- config
@@ -81,11 +81,39 @@ location /RequestDenied {
      return 412;
 }
 --- 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)
 --- main_config
 load_module $TEST_NGINX_NAXSI_MODULE_SO;
@@ -161,11 +189,11 @@ location /RequestDenied {
 }
 --- request
 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
 include $TEST_NGINX_NAXSI_RULES;
 --- config
@@ -185,17 +213,75 @@ location /RequestDenied {
 }
 --- more_headers
 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;
      IgnoreCIDR "2001:4860:4860::8888/128";
      DeniedUrl "/RequestDenied";

Vulnerable code: #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
    {
    }
=== TEST 1.2: IgnoreIP request with X-Forwarded-For allow (ipv4) 
GET /?a=buibui
=== TEST 1.3: IgnoreIP request with X-Forwarded-For allow (ipv6)
GET /?a=buibui
=== TEST 1.2: IgnoreCIDR request with X-Forwarded-For allow (no file) 
GET /?a=buibui
=== TEST 1.6: IgnoreCIDR request with X-Forwarded-For allow (ipv6)
=== TEST 1.7: Verify IgnoreCIDR 2001:4860:4860::8888/128 is converted to IgnoreIP
Fixed code:                 --with-http_realip_module \
=== TEST 1.2.1: IgnoreIP request with X-Forwarded-For allow without real_ip config (ipv4) 
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=<>
=== TEST 1.3.1: IgnoreIP request with X-Forwarded-For allow without reaL_ip config (ipv6)
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=<>
=== TEST 1.2.1: IgnoreCIDR request with X-Forwarded-For allow without real_ip config (no file)
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=<>
=== TEST 1.6.1: IgnoreCIDR request with X-Forwarded-For allow without real_ip config (ipv6)
--- 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=<>
=== 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
set_real_ip_from 127.0.0.1;
set_real_ip_from ::1/128;
real_ip_header X-Forwarded-For;