Skip to main content
Vulnerability Database/CVE-2026-87081

CVE-2026-87081: Perl Net::IDN::UTS46 DOS Vulnerability

CVE-2026-87081 is a denial of service flaw in Perl Net::IDN::UTS46 that enables CPU exhaustion through quadratic punycode encoding. This article covers the technical details, affected versions, and mitigation strategies.

Published:

CVE-2026-87081 Overview

CVE-2026-87081 is a CPU exhaustion vulnerability in the Net::IDN::UTS46 Perl module for versions before 2.590. The flaw resides in the to_ascii function, which punycode-encodes each label before applying the 63-byte DNS length limit. An attacker can submit an overlong label composed of distinct non-ASCII code points, triggering quadratic-time processing in encode_punycode before the length check rejects the input. Every ASCII conversion in the distribution routes through to_ascii, including domain_to_ascii and email_to_ascii, exposing any application that validates internationalized domain names or email addresses to remote denial of service.

Critical Impact

Unauthenticated attackers can trigger sustained CPU exhaustion on any Perl service that processes attacker-controlled internationalized domain or email input.

Affected Products

  • Net::IDN::UTS46 for Perl versions before 2.590
  • Net::IDN::Encode distribution consumers using domain_to_ascii
  • Net::IDN::Encode distribution consumers using email_to_ascii

Discovery Timeline

  • 2026-09-22 - CVE CVE-2026-87081 published to NVD
  • 2026-09-22 - Vulnerability disclosed on the Openwall oss-security mailing list
  • 2026-09-22 - Last updated in NVD database

Technical Details for CVE-2026-87081

Vulnerability Analysis

The vulnerability is an algorithmic complexity flaw classified as [CWE-407] (Inefficient Algorithmic Complexity). The to_ascii function in Net::IDN::UTS46 performs punycode encoding of each label before enforcing the DNS 63-byte length limit. The encode_punycode implementation in both the pure-Perl and XS backends mirrors the sample code in RFC 3492. Its outer loop iterates once per distinct non-ASCII code point and rescans the entire input on each iteration.

This yields runtime proportional to the square of the label length. An attacker who submits a label of several thousand distinct non-ASCII characters forces the encoder to perform work quadratic in that length before the 63-byte limit rejects the result. Because domain_to_ascii and email_to_ascii both funnel through to_ascii, any callable exposed to user-supplied domain or email strings inherits the vulnerability.

Root Cause

The ordering of operations places the expensive punycode transformation before the cheap length validation. The encoder should reject labels longer than 63 - length($IDNA_PREFIX) bytes up front, since punycode never shortens a label. Instead, the function commits full quadratic work only to discard the result.

Attack Vector

An unauthenticated remote attacker submits a single crafted label of distinct non-ASCII code points to any endpoint that invokes domain_to_ascii, email_to_ascii, or to_ascii. Typical exposures include mail servers validating envelope addresses, web applications normalizing user-supplied URLs, and API gateways parsing hostnames. Repeated submissions saturate CPU capacity and stall the process.

text
# Patch: Move the overlong-label check into to_ascii (lib/Net/IDN/UTS46.pm)
  splice @_, 1, 0, sub {
    local $_ = shift;
    if(m/\P{ASCII}/) {
+      ## punycode never shortens a label
+      croak "label too long [A4_2]" if length($_) > 63 - length($IDNA_PREFIX);
      eval { $_ = $IDNA_PREFIX . encode_punycode($_) };
      croak "$@ [A3]" if $@;
    }
# Source: https://github.com/robrwo/Net-IDN-Encode/commit/ea34f812d7dc67f3b211f4d92e74c6a7e24d764a.patch

Detection Methods for CVE-2026-87081

Indicators of Compromise

  • Sustained single-core CPU saturation in Perl worker processes handling domain or email input.
  • Request payloads containing hostname or email local-part labels longer than 63 bytes with many distinct non-ASCII code points.
  • Application timeouts or worker starvation coinciding with inbound requests carrying unusually long internationalized labels.

Detection Strategies

  • Instrument Net::IDN::UTS46::to_ascii call sites to record input length and wall-clock duration, then alert on outliers.
  • Inspect web and mail server access logs for hostnames or email addresses containing labels exceeding 63 bytes prior to normalization.
  • Correlate spikes in Perl CPU usage with concurrent HTTP or SMTP requests referencing IDN inputs.

Monitoring Recommendations

  • Track the installed version of Net-IDN-Encode across production Perl environments and flag anything below 2.590.
  • Set request-time budgets on endpoints that accept domain or email inputs and log requests that breach the budget.
  • Enable per-process CPU time limits and alert on repeated SIGXCPU or timeout events tied to IDN processing.

How to Mitigate CVE-2026-87081

Immediate Actions Required

  • Upgrade Net::IDN::Encode to version 2.590 or later on every Perl host that processes untrusted domain or email input.
  • Audit application code for callers of to_ascii, domain_to_ascii, and email_to_ascii and add pre-validation length limits.
  • Deploy request-size and per-label length caps at the reverse proxy or WAF layer for hostnames and email addresses.

Patch Information

The fix ships in Net-IDN-Encode-2.590-TRIAL. Two upstream commits address the issue: commit ea34f812 moves the overlong-label length check ahead of the punycode step in lib/Net/IDN/UTS46.pm, and commit 5ac33151 records the change and adds regression tests t/uts46_quadratic-pp.t and t/uts46_quadratic-xs.t. See the MetaCPAN release changes and the Openwall OSS-Security post for details.

Workarounds

  • Reject any label longer than 63 bytes before invoking to_ascii, domain_to_ascii, or email_to_ascii.
  • Wrap IDN conversion calls in a timeout using alarm or an equivalent guard to bound worst-case runtime.
  • Rate-limit or block requests containing hostnames or email addresses with dense non-ASCII content at the network edge.
bash
# Upgrade Net-IDN-Encode to the patched release
cpanm PJCJ/Net-IDN-Encode-2.590-TRIAL.tar.gz

# Verify installed version
perl -MNet::IDN::Encode -e 'print $Net::IDN::Encode::VERSION, "\n"'

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.