From 69a975a4b32887bff4b7692371836e88fb90ce98 Mon Sep 17 00:00:00 2001 From: Graham TerMarsch Date: Tue, 23 Jun 2026 19:44:38 -0700 Subject: [PATCH] Fixes CVE-2026-56017, which would SEGFAULT Perl. Much thanks to CPANSec for reporting the issue, and for providing a prototype fix. > CVE-2026-56017: > > JavaScript::Minifier::XS: NULL-pointer dereference (SIGSEGV) in regex/division disambiguator on attacker-supplied JS > > Trigger: the public minify() API on attacker-supplied JavaScript as small as a single / byte (also /x, /b/c, /re/). Any deployment that minifies untrusted or third-party JS is exposed. > > Impact: process crash -> denial of service. A one-byte input crashes the worker that minifies it; in a long-lived server (Plack/Catalyst/Mojolicious asset middleware, a CDN or on-the-fly minifier endpoint) that is a remote DoS. --- Changes | 3 +++ XS.xs | 7 ++++--- t/CVE-2026-56017.t | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100755 t/CVE-2026-56017.t diff --git a/Changes b/Changes index f163d62..ac8f62d 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,9 @@ Revision history for Perl extension JavaScript::Minifier::XS. {{$NEXT}} + - Fixes CVE-2026-56017, which caused Perl to SEGFAULT when calling + minify(). Thanks to CPANSec for raising the issue, and providing a + prototype fix. 0.15 2021-10-15 20:21:23-07:00 America/Vancouver - GH#8 - preserve newlines when collapsing whitespace; if a block of diff --git a/XS.xs b/XS.xs index 5123328..27e5a6a 100644 --- a/XS.xs +++ b/XS.xs @@ -446,13 +446,14 @@ Node* JsTokenizeString(JsDoc* doc, const char* string) { char ch = 0; /* find last non-whitespace, non-comment node */ - while (nodeIsWHITESPACE(last) || nodeIsCOMMENT(last)) + while (last && (nodeIsWHITESPACE(last) || nodeIsCOMMENT(last))) last = last->prev; - ch = last->contents[last->length-1]; + if (last && (last->length > 0)) + ch = last->contents[last->length-1]; /* see if we're "division" or "regexp" */ - if (nodeIsIDENTIFIER(last) && nodeEquals(last, "return")) { + if (last && nodeIsIDENTIFIER(last) && nodeEquals(last, "return")) { /* returning a regexp from a function */ _JsExtractLiteral(doc, node); } diff --git a/t/CVE-2026-56017.t b/t/CVE-2026-56017.t new file mode 100755 index 0000000..1b1f374 --- /dev/null +++ b/t/CVE-2026-56017.t @@ -0,0 +1,14 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use Test::More; +use JavaScript::Minifier::XS qw(minify); + +############################################################################### +# CVE-2026-56017 +eval { minify('/') }; +pass 'minified the JS without SEGFAULTing'; + +############################################################################### +done_testing();