[From nobody Sat Oct 31 01:53:05 2026
Received: (at submit) by bugs.debian.org; 22 Sep 2026 18:38:50 +0000
X-Spam-Checker-Version: SpamAssassin 4.0.1-bugs.debian.org_2005_01_02
 (2024-03-25) on buxtehude.debian.org
X-Spam-Level: 
X-Spam-Status: No, score=-9.9 required=4.0 tests=BAYES_00, FOURLA,
 FROMDEVELOPER, 
 NO_RELAYS,XMAILER_REPORTBUG autolearn=ham autolearn_force=no
 version=4.0.1-bugs.debian.org_2005_01_02
X-Spam-Bayes: score:0.0000 Tokens: new, 62; hammy, 150; neutral, 284; spammy,
 0. spammytokens: hammytokens:0.000-+--XDebbugsCc,
 0.000-+--X-Debbugs-Cc, 0.000-+--H*F:U*carnil, 0.000-+--H*Ad:N*Bug,
 0.000-+--HTo:N*Debian
Return-path: &lt;carnil@debian.org&gt;
Received: via submission by buxtehude.debian.org with esmtp (Exim 4.96)
 (envelope-from &lt;carnil@debian.org&gt;) id 1x95OE-001muk-0v
 for submit@bugs.debian.org; Tue, 22 Sep 2026 18:38:50 +0000
Content-Type: text/plain; charset=&quot;us-ascii&quot;
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
From: Salvatore Bonaccorso &lt;carnil@debian.org&gt;
To: Debian Bug Tracking System &lt;submit@bugs.debian.org&gt;
Subject: libnet-idn-encode-perl: CVE-2026-74765 CVE-2026-74766 CVE-2026-87078
 CVE-2026-87079 CVE-2026-87080 CVE-2026-87081 CVE-2026-87082
Message-ID: &lt;179010232909.214696.10903342684901082474.reportbug@eldamar.lan&gt;
X-Mailer: reportbug 13.2.0+nmu1
Date: Tue, 22 Sep 2026 20:38:49 +0200
Delivered-To: submit@bugs.debian.org

Source: libnet-idn-encode-perl
Version: 2.500-5
Severity: important
Tags: security upstream
X-Debbugs-Cc: carnil@debian.org, Debian Security Team &lt;team@security.debian.org&gt;

Hi,

The following vulnerabilities were published for libnet-idn-encode-perl.

CVE-2026-74765[0]:
| Net::IDN::Punycode versions before 2.590 for Perl allow an out-of-
| bounds read via integer overflow of the delta accumulator in
| encode_punycode.  The XS backend keeps the punycode delta, and the
| digit index derived from it, in a signed int. The accumulation
| `delta += (m-n) * (h+1)` has no overflow check, so a large enough
| code point wraps the delta and the digit index leaves the range of
| the 36-entry digit table. The bound before the final table access
| tests only for an index above 36, so a negative index passes it, as
| does 36 itself. Perl strings hold code points beyond the Unicode
| range, and one such code point overflows the accumulation on its
| own. Valid input wraps it as well, for example 1927 ASCII letters
| followed by U+10FFFF. The conversion functions encode a label before
| they check its length, so a long label reaches the encoder through
| the documented API.  Only the XS backend is affected.  Encoding an
| attacker-supplied string copies a byte from outside the digit table
| into the encoded result or crashes the process.


CVE-2026-74766[1]:
| Net::IDN::Punycode versions from 2.301 before 2.590 for Perl allow a
| heap use-after-free via a decoded code point that reallocates the
| output buffer in decode_punycode.  The XS backend inserts each
| decoded code point into the string buffer of the scalar it returns.
| decode_punycode computes the insertion pointer first and only then
| grows the buffer when the code point does not fit. The growth
| reallocates the buffer and updates every pointer except the
| insertion pointer, so the move that follows and the write of the
| code point go through a freed pointer. The buffer starts at twice
| the label length, and a code point above U+FFFF takes four bytes in
| the output, so a label of such code points outgrows it and forces
| the reallocation.  Version 2.301, the fix for CVE-2016-15059,
| introduced the defect. Only the XS backend is affected.  Decoding an
| attacker-supplied punycode label reads and writes freed heap memory.


CVE-2026-87078[2]:
| Net::IDN::Punycode versions from 2.302 before 2.590 for Perl leak
| the output buffer on every rejected label in decode_punycode.  The
| XS backend allocates the scalar it returns before it validates the
| input, sizing the buffer at twice the input length. The scalar is
| released only on the success path, so each of the three croaks that
| reject a label leaves the scalar and its buffer allocated. Nothing
| bounds the label length in the to-Unicode direction, since the
| 63-byte DNS limit is checked only when converting to ASCII.  Only
| the XS backend is affected.  A sender who supplies invalid labels
| grows the process by twice the label length per rejected call, with
| no successful call needed.


CVE-2026-87079[3]:
| Net::IDN::Punycode versions before 2.590 for Perl allow CPU
| exhaustion via quadratic insertion cost when decoding a long label
| in decode_punycode.  The XS backend inserts each decoded code point
| into a UTF-8 buffer and finds the insertion point by scanning that
| buffer from the start, one character at a time. The scan runs once
| per code point over the output built so far, so the cost is
| quadratic in the label length. The pure-Perl backend downgrades its
| input to bytes so that substr can index it directly, but takes its
| working copy before the downgrade, so when the input carries the
| UTF-8 flag every substr on the copy scans from the start, with the
| same quadratic cost.  Nothing bounds the label length in the to-
| Unicode direction. The 63-byte DNS limit is checked only when
| converting to ASCII, so domain_to_unicode and uts46_to_unicode pass
| an attacker-supplied label of any length to the decoder.


CVE-2026-87080[4]:
| Net::IDN::Punycode::PP versions before 2.590 for Perl decode a
| truncated label to a name containing a character it never encoded in
| decode_punycode.  The pure-Perl decoder reads one digit at a time
| with four-argument substr and tests the result with defined to
| detect the end of the input. substr on an exhausted string returns
| the empty string rather than undef, so decoding continues past the
| end. The empty string converts to a digit value below the range,
| reducing the accumulator, and the decoder derives one extra code
| point and its position from it. The result is deterministic. The XS
| backend rejects the same label.  Net::IDN::Punycode uses this
| backend wherever the XS does not build.  The two backends disagree
| about what such a label means, so a sender can pick a label that one
| installation resolves to a name and another rejects.


CVE-2026-87081[5]:
| Net::IDN::UTS46 versions before 2.590 for Perl allow CPU exhaustion
| via quadratic punycode encoding of an overlong label before the
| length check in to_ascii.  to_ascii punycode encodes each label and
| only then applies the 63-byte DNS limit. encode_punycode in both
| backends follows the sample implementation in RFC 3492, whose outer
| loop runs once per distinct non-ASCII code point and scans the whole
| input each round, so a label of distinct non-ASCII characters costs
| the square of its length before the limit rejects it. Every ASCII
| conversion in the distribution, including domain_to_ascii and
| email_to_ascii, goes through to_ascii.


CVE-2026-87082[6]:
| Net::IDN::Punycode versions before 2.590 for Perl hang, crash or
| return a wrong label via unvalidated malformed UTF-8 in
| encode_punycode.  Neither backend checks that its input is well-
| formed UTF-8, so a string with the UTF-8 flag set over malformed
| bytes, as the :utf8 PerlIO layer produces from any malformed input,
| reaches the encoder unchecked. On perl 5.32 and later the XS backend
| reports a malformed sequence with a length of `(STRLEN)-1`, so the
| scan steps back one byte instead of forward and never ends. On
| earlier perls the XS returns a valid label for a different name. The
| pure-Perl backend runs a regex over the flagged string. Depending on
| the bytes, it aborts with SIGBUS on perl 5.28 and later, dies with a
| panic, or returns a wrong label.  The documented conversion
| functions match the label against Unicode properties first and that
| match dies on such a string, so only a direct call to
| encode_punycode reaches the defect. The decoder is not affected.  A
| direct caller encoding attacker-supplied bytes hangs, crashes or
| gets a label for a name the input never held.


If you fix the vulnerabilities please also make sure to include the
CVE (Common Vulnerabilities &amp; Exposures) ids in your changelog entry.

For further information see:

[0] https://security-tracker.debian.org/tracker/CVE-2026-74765
    https://www.cve.org/CVERecord?id=CVE-2026-74765
[1] https://security-tracker.debian.org/tracker/CVE-2026-74766
    https://www.cve.org/CVERecord?id=CVE-2026-74766
[2] https://security-tracker.debian.org/tracker/CVE-2026-87078
    https://www.cve.org/CVERecord?id=CVE-2026-87078
[3] https://security-tracker.debian.org/tracker/CVE-2026-87079
    https://www.cve.org/CVERecord?id=CVE-2026-87079
[4] https://security-tracker.debian.org/tracker/CVE-2026-87080
    https://www.cve.org/CVERecord?id=CVE-2026-87080
[5] https://security-tracker.debian.org/tracker/CVE-2026-87081
    https://www.cve.org/CVERecord?id=CVE-2026-87081
[6] https://security-tracker.debian.org/tracker/CVE-2026-87082
    https://www.cve.org/CVERecord?id=CVE-2026-87082

Regards,
Salvatore
]