CVE-2021-27191 (published 2021-02-11T18:15Z)

The get-ip-range package before 4.0.0 for Node.js is vulnerable to denial of service (DoS) if the range is untrusted input. An attacker could send a large range (such as 128.0.0.0/1) that causes resource exhaustion.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/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/JoeScho/get-ip-range
commit_details: repo_url: https://github.com/JoeScho/get-ip-range
author: JoeScho
author_date: 2021-02-10 22:48:28+00:00
msg: limit total IPs in range to avoid DoS
repository: repo_url: https://github.com/JoeScho/get-ip-range
repo_name: JoeScho/get-ip-range
description: Simple utility to convert either CIDR notation or two IP addresses to an array of the range of IP addresses
repo_language: TypeScript
owner: JoeScho
file_changes: filename: index.test.ts
change_type: ModificationType.MODIFY
diff: @@ -91,4 +91,16 @@ describe('for two IP addresses', () => {
   it('should support hyphenated range in IPv5', () => {
     expect(getIPRange('::ffff:102:304-::ffff:102:307')).toEqual(successResponsev6);
   });
+
+  it('should throw if the range is greater than 10000 default', () => {
+    const throwFn = () => getIPRange('128.0.0.0/1');
+    expect(throwFn).toThrow('Too many IPs in range. Total number: 2147483647. Max count is 10000, to increase, set the limit with the MAX_RANGE environment variable');
+  });
+
+  it('should throw if the range is greater than process.env.MAX_RANGE', () => {
+    process.env.MAX_RANGE = '5000';
+
+    const throwFn = () => getIPRange('128.0.0.0/1');
+    expect(throwFn).toThrow('Too many IPs in range. Total number: 2147483647. Max count is 5000, to increase, set the limit with the MAX_RANGE environment variable');
+  });
 });

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -2,6 +2,9 @@ import { toLong, fromLong } from 'ip';
 // @ts-ignore
 import { Address4, Address6 } from 'ip-address';
 
+// Set default max range
+let maxRange = 10000;
+
 const getIPv4 = (ip: string): Address4 | null => {
   try {
     return new Address4(ip);
@@ -24,6 +27,13 @@ const getRangev4 = (ip1: string, ip2: string) => {
   let firstAddressLong = toLong(ip1);
   const lastAddressLong = toLong(ip2);
 
+  const totalIPs = lastAddressLong - firstAddressLong;
+
+  // Prevent DoS
+  if (totalIPs > maxRange) {
+    throw new Error(`Too many IPs in range. Total number: ${totalIPs}. Max count is ${maxRange}, to increase, set the limit with the MAX_RANGE environment variable`)
+  }
+
   for (firstAddressLong; firstAddressLong <= lastAddressLong; firstAddressLong++)
     ips.push(fromLong(firstAddressLong));
 
@@ -48,6 +58,8 @@ const isCIDR = (ipCIDR: Address4 | Address6): boolean => Boolean(ipCIDR.parsedSu
 const isRange = (ipRange: string): boolean => ipRange.indexOf('-') !== -1;
 
 const getIPRange = (ip1: string, ip2?: string): Array<string> => {
+  maxRange = parseInt(process.env.MAX_RANGE || '10000');
+
   const ip1v4 = getIPv4(ip1);
   const ip1v6 = getIPv6(ip1);
 

programming_language: TypeScript