CVE-2026-19566 Overview
CVE-2026-19566 is a memory exhaustion vulnerability in the Net::CIDR::Set Perl module versions before 0.23. The flaw allows attackers to trigger unbounded memory allocation by supplying IPv6 CIDR strings with arbitrarily large prefix lengths. Any application that passes untrusted input into contains() or add() can be forced to allocate hundreds of megabytes from a single request. The vulnerability also produces malformed set ranges when prefix lengths exceed 128, causing contains() and set arithmetic to return incorrect results. The issue is tracked under [CWE-789: Memory Allocation with Excessive Size Value].
Critical Impact
A single IPv6 CIDR string such as ::/100000000 forces Net::CIDR::Set to build a 100 MB string and a 12.5 million element Perl array, exhausting process memory and enabling denial of service against any caller that processes untrusted CIDR input.
Affected Products
- Net::CIDR::Set for Perl, all versions before 0.23
- Applications using contains() with untrusted input, including IPv4-only sets
- Applications using add() to load CIDR data from external sources
Discovery Timeline
- 2026-08-12 - CVE-2026-19566 published to NVD
- 2026-08-12 - Last updated in NVD database
Technical Details for CVE-2026-19566
Vulnerability Analysis
The vulnerability resides in the IPv6 encoder of Net::CIDR::Set. The _encode method accepts any prefix length matching the regex (0|[1-9][0-9]*) and passes the value directly to _width2bits(). That function constructs a mask string using '1' x ($width + 8), allocating one character per bit of the requested prefix width. The _inc() method then unpacks the packed mask into a Perl array containing one scalar per byte.
Because the prefix length alone drives allocation size, a caller-controlled integer directly maps to memory usage. A value of 100000000 produces a 100 MB string and a Perl array of roughly 12.5 million elements. The parsing occurs on any value passed to contains() because that method builds a temporary set from its argument. The internal _guess_coder() tries the IPv4 coder first and then the IPv6 coder, so even an IPv4-only set expands an oversized IPv6 prefix length before the mixed address width check rejects it.
A secondary correctness issue arises when prefix lengths exceed 128. The value 2001:db8::/129 stringifies back unchanged, contains() of its own base address returns false, and removing it drops the base while the set still prints as covering it.
Root Cause
The root cause is missing bounds validation on the IPv6 netmask prefix length in lib/Net/CIDR/Set/IPv6.pm. The _encode method validated only the regex shape of the prefix value, not its numeric upper bound of 128 bits.
Attack Vector
An unauthenticated remote attacker submits a crafted IPv6 CIDR string to any interface that eventually calls contains() or add(). Because CIDR parsing runs before address family validation, exploitation does not require the target to use IPv6 sets. The attacker needs only the ability to influence a single string argument.
The upstream patch adds a single guard clause to _encode before the mask expansion:
my ( $self, $ip ) = @_;
if ( $ip =~ m{\A([0-9A-Fa-f:]+)/(0|[1-9][0-9]*)\z} ) {
my $mask = $2;
+ return if $mask > 128;
return unless my $addr = _pack( $1 );
return unless my $bits = _width2bits( $mask, 128 );
return ( $addr & $bits, Net::CIDR::Set::_inc( $addr | ~$bits ) );
Source: GitHub Patch for Net-CIDR-Set
Detection Methods for CVE-2026-19566
Indicators of Compromise
- Perl processes consuming abnormal amounts of resident memory shortly after handling network input containing / characters
- Application logs containing IPv6 CIDR strings with prefix lengths greater than 128, such as ::/129 or values with many digits
- Out-of-memory kills or process restarts correlated with requests carrying CIDR-formatted parameters
Detection Strategies
- Inspect HTTP request bodies, query strings, and API payloads for IPv6 CIDR patterns where the prefix length exceeds 128
- Audit Perl applications for direct or indirect use of Net::CIDR::Set::contains and Net::CIDR::Set::add on untrusted input
- Deploy input validation at the web application firewall layer to reject CIDR strings with numerically unreasonable prefixes
Monitoring Recommendations
- Track memory allocation growth rates on Perl worker processes and alert on sudden spikes above baseline
- Correlate process crashes with recent request payloads to identify exploitation attempts
- Enable CPAN dependency scanning in CI/CD pipelines to flag Net::CIDR::Set versions below 0.23
How to Mitigate CVE-2026-19566
Immediate Actions Required
- Upgrade Net::CIDR::Set to version 0.23 or later on all Perl installations
- Enumerate applications that depend on this module and identify code paths passing untrusted input to contains() or add()
- Apply memory limits (ulimit -v, systemd MemoryMax) to Perl worker processes as a defense-in-depth control
Patch Information
The fix was released in Net::CIDR::Set version 0.23 on CPAN. The commit e16b27d in the GitHub repository for perl-Net-CIDR-Set adds a bounds check that returns early when the mask exceeds 128. Details are available in the GitHub Security Advisory GHSA-grjr-r4x5-mx4p and the MetaCPAN release changes for Net-CIDR-Set 0.23.
Workarounds
- Validate CIDR input at the application boundary and reject any string where the prefix length after / exceeds 128 for IPv6 or 32 for IPv4
- Wrap calls to contains() and add() in a length check on the raw input to bound the attack surface until patching completes
- Enforce per-process memory limits so that exploitation attempts fail closed rather than exhausting host memory
# Upgrade Net::CIDR::Set to the patched release
cpanm Net::CIDR::Set@0.23
# Verify installed version
perl -MNet::CIDR::Set -e 'print $Net::CIDR::Set::VERSION, "\n"'
# Defense-in-depth: cap virtual memory for Perl workers
ulimit -v 524288
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

