]> git.kaiwu.me - nginx.git/commitdiff
GeoIP: rejected out-of-range coordinates from MMDB lookups
authorY.Horie <u5.horie@gmail.com>
Tue, 27 Oct 2026 22:25:20 +0000 (07:25 +0900)
committerNITIN SWAMI <n.swami@f5.com>
Thu, 5 Nov 2026 05:24:49 +0000 (10:54 +0530)
The $geoip_latitude and $geoip_longitude values are formatted with
ngx_sprintf(buf, "%.4f", value) into a buffer sized for a coordinate,
but the DOUBLE/FLOAT value is taken from the database with no range
check.  A crafted or corrupted MMDB can store a huge magnitude (e.g.
1e30 or an infinity), and ngx_sprintf, which is unbounded, then writes
past the buffer in the request or connection pool.

Coordinates outside [-180, 180] are now rejected, so the variables
report "not found" as they do for a missing entry.  The comparison also
rejects a NaN.

Closes: https://github.com/nginx/nginx/issues/1907
src/http/modules/ngx_http_geoip_module.c
src/stream/ngx_stream_geoip_module.c

index 05f3d8aa384438eda7f14a549f1eeffd87c9a25a..cee2c4957ee02beb49137bf5fcfa22476fe16d1a 100644 (file)
@@ -35,6 +35,8 @@
 #define NGX_GEOIP_CITY_DMA_CODE        10
 #define NGX_GEOIP_CITY_AREA_CODE       11
 
+#define NGX_GEOIP_MAX_COORD            180
+
 
 typedef struct {
 #if (NGX_HAVE_GEOIP)
@@ -1193,15 +1195,23 @@ ngx_http_geoip_float(MMDB_entry_s *entry, const char **path, double *value)
 
     case MMDB_DATA_TYPE_DOUBLE:
         *value = entry_data.double_value;
-        return NGX_OK;
+        break;
 
     case MMDB_DATA_TYPE_FLOAT:
         *value = entry_data.float_value;
-        return NGX_OK;
+        break;
 
     default:
         return NGX_DECLINED;
     }
+
+    /* the range of a coordinate in degrees; NaN fails the comparison */
+
+    if (!(*value >= -NGX_GEOIP_MAX_COORD && *value <= NGX_GEOIP_MAX_COORD)) {
+        return NGX_DECLINED;
+    }
+
+    return NGX_OK;
 }
 
 
index 67896837d503d2564f205403ec7c5263852686b4..8122003942b584e7bd7a92615549258dbaaea9c7 100644 (file)
@@ -35,6 +35,8 @@
 #define NGX_GEOIP_CITY_DMA_CODE        10
 #define NGX_GEOIP_CITY_AREA_CODE       11
 
+#define NGX_GEOIP_MAX_COORD            180
+
 
 typedef struct {
 #if (NGX_HAVE_GEOIP)
@@ -1155,15 +1157,23 @@ ngx_stream_geoip_float(MMDB_entry_s *entry, const char **path, double *value)
 
     case MMDB_DATA_TYPE_DOUBLE:
         *value = entry_data.double_value;
-        return NGX_OK;
+        break;
 
     case MMDB_DATA_TYPE_FLOAT:
         *value = entry_data.float_value;
-        return NGX_OK;
+        break;
 
     default:
         return NGX_DECLINED;
     }
+
+    /* the range of a coordinate in degrees; NaN fails the comparison */
+
+    if (!(*value >= -NGX_GEOIP_MAX_COORD && *value <= NGX_GEOIP_MAX_COORD)) {
+        return NGX_DECLINED;
+    }
+
+    return NGX_OK;
 }