CVE-2026-15534
Executive Summary
CVE-2026-15534 is a critical memory corruption vulnerability in the Perl programming language's regex engine (regcomp.c / regexec.c), affecting all versions through 5.45.1. The flaw resides in S_regmatch's handling of the superlinear cache (SLAB), where a signed 32-bit integer overflow occurs when computing the required cache size for large subject strings matched against patterns with multiple WHILEM nodes. An attacker capable of supplying a crafted regex pattern and a subject of approximately 286 million bytes can trigger out-of-bounds heap reads and writes, leading to process crashes or arbitrary heap corruption. The vulnerability is currently UNPATCHED with no vendor fix, workaround, or public exploit code available, yet the attack surface includes any Perl-based application that processes untrusted regex patterns against large inputs (web application firewalls, log processors, mail filters, etc.).
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The vulnerability exists in Perl's regex execution engine, specifically within the S_regmatch function in regexec.c. The engine employs a "superlinear cache" to optimize patterns containing WHILEM (loop) nodes. This cache is a bit-array designed to track whether a particular subject position has already been visited for a given loop-iteration state, preventing exponential backtracking in superlinear patterns.
Cache Size Calculation Overflow:
The cache allocation logic computes:
cache_size_bits = (subject_length + 1) * number_of_WHILEM_nodes
This product is stored in a signed 32-bit integer (I32). For a subject of length 286,331,153 bytes (0x11111111) matched against a pattern containing exactly 15 participating WHILEM nodes:
286,331,153 * 15 = 4,294,967,295 (0xFFFFFFFF)
Since 0xFFFFFFFF exceeds the signed 32-bit maximum (0x7FFFFFFF = 2,147,483,647), the value wraps to -1. The allocation code then performs different handling for negative values — it interprets the wrap as a need for a minimal cache. Specifically, the engine stores the count as 14 (the calculation -1 & 0x0F path) resulting in a 2-byte heap allocation (14 bits + alignment = 2 bytes).
Out-of-Bounds Access:
Once the undersized 2-byte cache is allocated, the regex engine continues matching. As the regex engine advances through the subject at real match positions (e.g., position 100,000), it indexes into the cache using:
cache_index = (real_match_position + 1) * node_number
Every read at position > 14 or node > 1 accesses memory far beyond the 2-byte allocation boundary — a classic heap buffer over-read. On pattern failure, the CACHEsayNO macro performs a write operation setting a bit at an out-of-bounds offset, causing a heap buffer overflow write. This write can corrupt adjacent heap metadata or attacker-controlled data.
Trigger Requirements:
- Subject length: Must be ≥ 286,331,153 bytes (~273 MB) — under normal conditions, an attacker must deliver a payload of this size.
- Pattern shape: Must contain ≥ 15 WHILEM nodes (e.g.,
(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a)*or similar alternation/loop constructs). - Memory allocation: The heap allocator must place the 2-byte cache adjacent to other writable heap regions for the write primitive to be useful.
The vulnerability is memory-safety critical (CWE-125 — Out-of-bounds Read, though the write component extends to CWE-787). It requires local or remote code execution context depending on the deployment: a network-facing Perl service (e.g., CGI application, email filter, or log analyzer) that passes user-supplied strings (URLs, email subjects, log lines) directly to qr// or m// operators with complex patterns.
Exploitation Scenarios
Attack Chain: Remote Code Execution via Per-Mail Exim/Postfix Regex Filter
Reconnaissance: The attacker identifies a mail server running a Perl-based content filter (e.g., SpamAssassin rules, custom Perl milter) that applies regex to email body/subject. Alternatively, target a Perl-based web application (ModPerl, CGI) where a regex is applied to query parameters or uploaded file contents.
Weaponization:
- Craft a regex pattern:
^((a|b|c|d|e|f|g|h|i|j|k|l|m|n|o)*)\1$— this creates multiple WHILEM nodes (each alternation branch adds a node;*adds another;\1backreference ties them). Total ≥ 15 WHILEM nodes. - Generate a subject string:
"a" x 286331154 . "x"(273 MB of repeated 'a' followed by a single 'x' to force failure and trigger theCACHEsayNOwrite path).
- Craft a regex pattern:
Delivery/Trigger:
- Send an email with the 273 MB payload as the body, ensuring the Perl filter processes it. For a web application, POST the payload to a parameter that is regex-validated.
- The Perl process allocates the 2-byte cache due to integer overflow, then starts matching. As the state machine advances through the 286M positions, it performs OOB reads at every cache check.
Memory Corruption & Execution:
- The OOB write on failure corrupts heap metadata adjacent to the cache allocation. In a perl interpreter, this can overwrite the
SVs(scalar values) header, changing a string's length/pointer fields to an attacker-controlled address. - The attacker previously places shellcode or a ROP chain in the 273MB payload (which remains in memory). By corrupting an SV to point at the payload, the attacker triggers
sv_getsorsv_setsvto copy memory, eventually redirecting execution to the injected shellcode. - Post-exploitation: The Perl process (often running as
nobodyorvmail) is hijacked; the attacker obtains code execution on the mail server, pivoting to the network.
- The OOB write on failure corrupts heap metadata adjacent to the cache allocation. In a perl interpreter, this can overwrite the
Impact: Full server compromise, mail store exfiltration, lateral movement to internal LDAP/database services, and potential for persistent backdoor via Perl module injection (
@INCpoisoning).
Impact Assessment
Business Impact: Critical — the vulnerability enables remote code execution in any non-hardenened Perl deployment. Given Perl's ubiquity in legacy infrastructure (cron scripts, system utilities, web backends, network appliances), exploitation can lead to full system compromise. The 273MB payload size is a significant restriction, but network throughput in enterprise environments (1Gbps+) makes delivery feasible in ~2 seconds.
Affected Systems: All Perl versions through 5.45.1 (the latest as of advisory). This includes:
- Linux/Unix distributions (Ubuntu, Debian, RHEL, CentOS) with system Perl
- Windows ActivePerl/Strawberry Perl installations
- Embedded appliances using Perl for management interfaces (network gear, storage arrays)
- Web servers running ModPerl, CGI, or PSGI/Plack applications
Blast Radius: The vulnerability is reachable remotely if any Perl script processes attacker-controlled input through regex operations over 273MB. In practice, this restricts to:
- High-volume mail filter systems (postfix tarpit)
- Log aggregation platforms (rsyslog → Perl parser)
- Security scanning tools that regex large packet captures.
- Inaccessible to most small-scope applications that limit input sizes.
CVSS Context (N/A): The CVSS has not been scored due to the vendor not responding. In a reasonable assessment, this would rate 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) given remote trigger with no privileges, but confirm with vendor updates.
Detection Guidance
Sigma Rule
title: Perl Regex Cache Overflow Attempt - Large Subject with Complex Pattern
id: 6f3a9c21-8aa7-4e33-9c54-1b1f7d2a5c90
status: experimental
description: Detects process crashes or abnormal memory behavior in perl when handling regex operations with extremely large subject strings and high node complexity patterns.
author: valtersit Threat Intel
logsource:
category: process_monitoring
product: linux
detection:
selection_proc:
Image|endswith: '/perl'
selection_args:
CommandLine|contains:
- 'm/'
- 's/'
- 'qr'
selection_size:
# Subject size > 250MB heuristic - check for large memory allocations
MemorySize|gte: 300MB
condition: selection_proc and selection_args and selection_size
timeframe: 5s
level: high
falsepositives:
- Legitimate large file processing (e.g., bioinformatics regex)
- Data mining scripts over multi-GB logs
fields:
- Image
- CommandLine
- MemorySize
- User
YARA Rule
rule Perl_Regex_Cache_Overflow_CVE_2026_15534 {
meta:
author = "valtersit Threat Intel"
description = "Detects Perl regex patterns containing >=15 alternations/loops that would trigger WHILEM node overflow against large input."
cve = "CVE-2026-15534"
date = "2026-06-01"
strings:
// Pattern content triggers for =~ m// or =~ s// with 15+ alternations (WHILEM nodes)
$regex_alternation_mult = /(?:\|[a-z]){14,}/ nocase
$regex_loop_nested = /\((?:[a-z]\|){10,}[a-z]\)\*/ nocase
// Large input size heuristic (look for lengths >= 0x11111111 = 286331153)
$big_length = {11 11 11 11} // 286331153 decimal in little-endian
condition:
($regex_alternation_mult or $regex_loop_nested) and $big_length
}
Suricata IDS Rule
alert http any any -> any any (msg:"PERL CVE-2026-15534 Regex Cache Overflow Trigger";
flow:established; content:"a"; http_client_body;
content:"|7c|" // pipe character = |
within:2048; http_client_body;
dsize:>286331100; sid:202615534; rev:1;
classtype:attempted-admin; metadata:cve CVE-2026-15534)
Note: Network detection of this attack requires deep packet inspection of >273MB request bodies. This rule triggers on HTTP POST bodies exceeding the threshold with regex-like alternation patterns.
Elastic Detection
sequence by process.entity_id
with maxspan=10s
[ process where process.name == "perl"
and (process.args : "*.pl" or process.args : "-e*")
]
[ file where process.name == "perl"
and file.size > 286331153
]
[ process where process.name == "perl" and event.type == "end"
and process.exit_code < 0 // negative exit code = signal (crash)
]
Splunk SPL Query
index=syslog sourcetype=linux_audit
| search (process="perl" OR comm="perl")
| where (bytes_in > 286331153 OR mem_vsz > 300000000)
| eval crash = if(exit_code < 0 OR signal IS NOT NULL, "true", "false")
| search crash="true"
| stats count BY host, user, process, cmdline
| where count > 0
| head 50
Additional companion query for regex pattern correlation:
index=web_security sourcetype=access_combined
| where bytes > 286331153 AND requested_url LIKE *%7C%* // %7C = URL-encoded |
| stats count BY src_ip, dest_host, http_method
Wazuh OSSEC Rule
<group name="perl,">
<rule id="100534" level="12">
<decoded>alert</decoded>
<program_name>^perl$</program_name>
<description>CVE-2026-15534: Perl regex engine heap overflow trigger detected - large subject/pattern combination</description>
<match>Out of memory|panic|Segmentation fault|Abort trap</match>
<regex>^perl\[[\d]+\]: error</regex>
<group>local,pci_dss_11.4,gdpr_IV_35.7.d</group>
<mitre>
<id>T1190</id>
</mitre>
</rule>
<rule id="100535" level="8">
<if_sid>100534</if_sid>
<match>regexec\.c|regmatch</match>
<description>CVE-2026-15534: Perl regex engine crash confirmed in regexec.c context</description>
</rule>
</group>
Mitigation & Patch Guidance
Patch Status: UNPATCHED — No vendor fix exists as of this report. The Perl security team has been notified (CNA: Perl, referenced via NVD), but no patch confidence is available.
Immediate Mitigations (temporary):
- Input size boundary: Implement application-level limits to reject regex subjects > 100MB. In Perl, wrap processing:
die "Input too large" if length($input) > 100_000_000; - Regex pattern complexity limit: Install
re::engine::Pluginor useRegexp::Parserto reject patterns with >10 alternations/loops at runtime. - Resource limits: Set
RLIMIT_ASandRLIMIT_DATAviasetrlimit()in the Perl wrapper to cap memory allocation. A crash is preferable to corruption. - Platform-level guard: Run Perl services in a sandbox (gVisor, Firecracker, or Docker with
--memory=300m) to contain heap corruption attempts.
Patch/Upgrade Path (when available):
- Monitor https://perl.org and the perl5-porters mailing list for a release deviating from 5.45.2. Expect a patch that:
- Changes
I32toSSize_torSTRLENfor the cache size calculation. - Adds an explicit overflow check:
if (total_bits > 0x7FFFFFFF) { deny cache or split }.
- Changes
- Apply via
perlbrewor distro backport once confirmed.
Long-Term Hardening:
- Replace complex regexes with state machine parsers (e.g.,
Parse::RecDescentor handwritten parsers) for untrusted input. - Upgrade RHEL/Debian baselines to use
perl 5.36+with security backports from distro maintainers. - Audit all Perl code with
perlcriticform//over user input; mandateuse re 'strict';anduse warnings 'FATAL'=> 'all'. - Implement WAF rules blocking request bodies > 250MB against Perl-backed applications.
References
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2026-15534
- MITRE CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-15534
- Perl Bug Tracker (pending): https://github.com/Perl/perl5/issues (search "CVE-2026-15534")
- Perl 5 Porters Mailing List Archive: https://www.nntp.perl.org/group/perl.perl5.porters/
- CWE-125 Reference: https://cwe.mitre.org/data/definitions/125.html
Exploitation in the wild: No known campaigns, exploit code, or CISA KEV inclusion as of this report. Monitoring continues.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.