CVE-2026-13221 Fix: Perl 5.38–5.43.9 Regexes Return Wrong Results

CVE-2026-13221 can make Perl 5.38 through 5.43.9 silently return the wrong result for unusually large regular expressions, potentially breaking access controls, filtering rules, and service logic without producing an error. The flaw is fixed upstream in the Perl 5.43.10 development line and is included in the forthcoming Perl 5.44.0 release, but widely deployed stable packages and Windows distributions may still require vendor updates or backports.
The vulnerability was published on July 15, 2026, through the CVE system and Microsoft’s Security Update Guide. Perl’s own release documentation describes it as a 16-bit overflow in the regular-expression trie optimizer, while Debian’s security tracker currently lists its packaged Perl releases as vulnerable and not yet fixed.
This is not a vulnerability in Windows itself, and Microsoft has not issued a Windows KB update for it. It matters on Windows because Perl is frequently installed through Strawberry Perl, Cygwin, MSYS2, development toolchains, legacy management applications, or software that embeds a private Perl interpreter.

Futuristic cybersecurity dashboard shows a 16-bit overflow warning, code, servers, and allow/deny policy gates.A Regex Can Fail Without Looking Broken​

The trigger is an alternation containing more than roughly 65,535 fixed-string branches. Perl may optimize a pattern such as (?:word1|word2|word3|...) into a trie, a tree-like structure designed to test a large collection of strings more efficiently than evaluating each alternative separately.
Inside Perl_study_chunk, the distance between the first branch and a shared tail is stored in a 16-bit field. Once the compiled structure exceeds what that field can represent, the value wraps and the trie’s match-decision data is truncated.
The dangerous part is the absence of a reliable failure signal. Instead of rejecting the pattern or terminating compilation, affected Perl versions can produce:
  • False positives, in which a string matches even though no valid branch accepts it.
  • False negatives, in which a string that should match is rejected.
  • A memory-corruption diagnostic or crash in some debugging configurations.
GitHub issue 23388 originally documented the problem in June 2025 as “regexp memory corruption with large tries.” The reporter reproduced a crash with Perl 5.38.2, 5.40.2, and a release candidate for Perl 5.42, while Perl 5.36.0 was not affected.
The later CVE analysis focuses on the broader and more consequential behavior: even when Perl does not crash, the compiled regex may simply make the wrong decision.
That distinction matters. A crash is visible and can usually be handled as an availability event. A silently incorrect match can cross a security boundary while logs, exception handlers, and monitoring systems continue to report normal operation.

The 65,535-Branch Requirement Narrows the Attack Surface​

Most handwritten regular expressions come nowhere near the trigger. A source file containing more than 65,535 literal alternatives would be conspicuous, expensive to maintain, and likely slow to compile even without the bug.
The realistic exposure lies in applications that generate patterns from data. Perl software may build large alternations from domain blocklists, routing tables, usernames, product identifiers, file signatures, policy entries, or other imported datasets. An attacker who can add enough entries, influence their ordering, or submit a preconstructed pattern may be able to push the optimizer across the boundary.
Exploitation therefore depends heavily on application design. A remotely supplied string being tested by a fixed regex is not enough by itself; the vulnerable condition concerns the construction and compilation of the pattern. Administrators should concentrate on systems where untrusted or semi-trusted data becomes regex source code.
Potentially serious cases include a generated regex used to:
  • Decide whether a user, tenant, or resource identifier is allowed.
  • Reject blocked hostnames, paths, commands, or file names.
  • Route requests to different handlers.
  • Select records for deletion, quarantine, or processing.
  • Apply allowlists or denylists to network and application traffic.
Microsoft’s listing describes a severe availability consequence, including the possibility of denying access to an affected resource. That is plausible where false negatives block legitimate requests or malformed generated patterns repeatedly disrupt a service. However, the upstream description also points to integrity failures: a false positive may permit something that policy intended to reject.
CVE-2026-13221 should not be treated as a generic unauthenticated remote denial-of-service flaw in every Perl installation. The attacker generally needs a path to influence an exceptionally large generated regex, and the consequence is determined by what the application does with the result.

The Fix Sacrifices an Optimization Before It Sacrifices Correctness​

The upstream correction is deliberately conservative. Commit 03f74bbbd3a68350d926ee93d56ee4808c28c4c7 adds a size check in regcomp_study.c and declines to create a trie when the distance involved would reach the 16-bit limit.
Perl’s existing design is intended to divide oversized tries into chunks that fit internal limits. According to the commit explanation, a sequence of branches containing TAIL operands could bypass that protection because Perl combined the branches and used the final shared tail.
Rather than redesigning trie construction late in the Perl 5.44 development cycle, the patch leaves an oversized sequence unoptimized. That may make compilation or matching slower for a pathological expression, but it preserves correct results. For a security fix, that is the right trade.
The vulnerable behavior was introduced by an upstream change included in Perl 5.37.10, the development series that led to stable Perl 5.38. This provides a more useful boundary than the CVE wording “versions through 5.43.9,” which could be read as implicating every historical Perl release.
Based on the upstream history:
  • Perl 5.36 and earlier are not affected by this specific regression.
  • Perl 5.38, 5.40, and 5.42 release families should be considered affected unless their distributor has backported the fix.
  • Perl 5.43.9 and earlier affected development builds are vulnerable.
  • The correction landed in Perl 5.43.10 and appears in the Perl 5.44 release documentation.
As of July 15, CPAN lists Perl 5.44.0 RC2, released July 8, rather than a final 5.44.0 tarball. Production administrators should generally prefer a maintained vendor package containing the backport over replacing a stable interpreter with a release candidate.

Windows Fleets Need an Interpreter Inventory, Not Windows Update​

Windows 10 and Windows 11 do not include Perl as a standard operating-system component. Running Windows Update alone therefore will not resolve CVE-2026-13221 in a separately installed interpreter.
Administrators can begin by locating active interpreters and recording their build information:
Code:
Get-Command perl -All
perl -v
perl -V
The first command helps identify multiple copies exposed through PATH; perl -V provides the detailed configuration needed to distinguish Strawberry Perl, Cygwin, MSYS2, and custom builds. Applications may also carry perl.exe in private directories that are not represented in the system or user path, so software inventories and filesystem searches remain necessary.
Strawberry Perl 5.40.4.1 and 5.42.0.1 fall within affected upstream families unless their maintainers issue a build with the patch applied. The version number alone will not reveal a downstream backport, making distributor release notes and package changelogs important.
The same caution applies to appliances and Windows applications that embed Perl. Updating a system-wide Strawberry installation does not replace a private interpreter shipped inside another product. Conversely, removing an unused global Perl installation will not protect a service running its own bundled runtime.
Until patched packages are available, application owners can reduce exposure by avoiding the construction of giant alternation expressions. Large fixed-string sets are often better represented as hashes, database lookups, dedicated trie libraries, or smaller regex batches with explicit limits. Any code that incorporates user-controlled values into regex source should already quote those values with quotemeta or \Q...\E, but quoting alone does not prevent this branch-count overflow.
The immediate priority is to identify Perl 5.38, 5.40, and 5.42 runtimes that compile generated allowlists or denylists. Those are the installations where CVE-2026-13221 can turn an internal optimization detail into a silent security-policy failure, and where waiting for an obvious crash may mean waiting for the wrong warning signal.

References​

  1. Primary source: MSRC
    Published: 2026-07-15T01:01:27-07:00
  2. Related coverage: sources.debian.org
 

Back
Top