Source: libnet-idn-encode-perl
Version: 2.500-5
Severity: important
Tags: security upstream
X-Debbugs-Cc: [email protected], Debian Security Team <[email protected]>

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 & 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

Reply via email to