Skip to main content
CVE Vulnerability Database

CVE-2026-9516: Cpanel::JSON::XS Perl DoS Vulnerability

CVE-2026-9516 is a denial of service vulnerability in Cpanel::JSON::XS for Perl caused by UTF-8 BOM handling errors. Attackers can crash applications using malformed input. This article covers technical details, affected versions, impact, and mitigation strategies.

Published:

CVE-2026-9516 Overview

CVE-2026-9516 is a denial of service vulnerability in Cpanel::JSON::XS versions before 4.41 for Perl. The flaw triggers when decode_json() processes input prefixed with a UTF-8 byte order mark (BOM) and a filter_json_object callback throws an exception. The decoder advances the input scalar's string pointer past the 3-byte BOM using SvPV_set() but restores it only on the normal return path. When a callback croaks, the scalar retains a corrupted pointer and shortened length. Freeing the scalar later passes an invalid pointer to the allocator, causing the Perl interpreter to abort.

Critical Impact

A single BOM-prefixed JSON document combined with a throwing filter callback crashes any caller of decode_json(), producing a SIGABRT and terminating the host process.

Affected Products

  • Cpanel::JSON::XS Perl module, all versions before 4.41
  • Perl applications using decode_json() with filter_json_object callbacks
  • Downstream distributions and web services bundling vulnerable releases

Discovery Timeline

  • 2026-06-03 - CVE-2026-9516 published to NVD
  • 2026-06-03 - Public discussion on the OpenWall oss-security mailing list
  • 2026-06-03 - Last updated in NVD database

Technical Details for CVE-2026-9516

Vulnerability Analysis

The defect lives in the BOM-handling branch of the XS decoder in XS.xs. To skip a leading 3-byte UTF-8 BOM, the code mutates the input SV in place by calling SvPV_set(string, SvPVX_mutable(string) + 3) and SvCUR_set(string, len - 3). This shifts the scalar's internal buffer pointer forward without allocating new storage. The pointer restoration runs only at the end of the normal decode path.

When a user-supplied filter_json_object callback raises a Perl exception, control unwinds through croak() and bypasses the cleanup logic. The scalar is left holding a pointer that no longer matches the start of its allocated buffer. Any later operation that frees the SV calls the allocator with the offset pointer, triggering an abort inside the memory manager. The classification aligns with [CWE-755: Improper Handling of Exceptional Conditions].

Root Cause

The root cause is missing exception-safe cleanup around in-place scalar pointer mutation. The decoder treats BOM skipping as a permanent edit until a final restore, rather than confining the change to a scope that unwinds on both normal and exceptional return.

Attack Vector

Exploitation requires that an application accept attacker-controlled JSON input and register a filter_json_object callback that can throw. Any reachable code path satisfying both conditions can be crashed by sending a document beginning with the UTF-8 BOM bytes EF BB BF. The attack is network-reachable, requires no authentication, and produces process termination.

text
         converted = 1 + (json->flags & F_UTF8);
         json->flags |= F_UTF8;
         offset = 3;
-        SvPV_set(string, SvPVX_mutable (string) + 3);
-        SvCUR_set(string, len - 3);
         SvUTF8_on(string);
         /* omitting the endian name will skip the BOM in the result */
       } else if (len >= 4 && memEQc(s, UTF32BOM)) {

Source: GitHub Patch Commit — the fix removes the in-place SvPV_set and SvCUR_set calls so the input scalar is never left with a corrupted pointer when a callback throws.

Detection Methods for CVE-2026-9516

Indicators of Compromise

  • Unexpected SIGABRT terminations of Perl worker processes or web application servers handling JSON input.
  • Core dumps showing abort frames inside perl_free, Safefree, or glibc allocator routines following decode_json activity.
  • Crash bursts correlated with inbound requests whose JSON bodies start with the bytes EF BB BF.

Detection Strategies

  • Inventory installed Perl modules and flag any Cpanel::JSON::XS release earlier than 4.41 using cpan -D Cpanel::JSON::XS or package manager queries.
  • Static-scan application code for filter_json_object usage combined with calls that may die or croak inside the callback.
  • Replay traffic captures in staging with BOM-prefixed payloads to confirm whether vulnerable code paths abort.

Monitoring Recommendations

  • Alert on SIGABRT and abnormal exit codes from Perl-based services such as mod_perl, Plack, and cPanel components.
  • Log and sample inbound JSON request prefixes at the web tier to surface BOM-prefixed payloads from untrusted clients.
  • Track module version drift across hosts so that downgrades to pre-4.41 releases trigger configuration alerts.

How to Mitigate CVE-2026-9516

Immediate Actions Required

  • Upgrade Cpanel::JSON::XS to version 4.41 or later across all systems that decode untrusted JSON.
  • Audit applications for filter_json_object and filter_json_single_key_object callbacks that can throw exceptions, and add defensive eval blocks where appropriate.
  • Restart long-running Perl services after the upgrade to ensure no vulnerable copies remain resident in memory.

Patch Information

The upstream fix is in commit dfe1b41a36caba51dc12a2917fe50285d1ffaa7b and is released as Cpanel-JSON-XS-4.41 on CPAN. References: GitHub Patch Commit, MetaCPAN Release Changes, and OpenWall OSS-Security Discussion.

Workarounds

  • Strip a leading UTF-8 BOM from input before invoking decode_json when filter callbacks are in use.
  • Wrap any filter_json_object callback so it returns sentinel values instead of calling die or croak.
  • Restrict JSON intake to authenticated clients until the patched module is deployed.
bash
# Upgrade Cpanel::JSON::XS to the fixed release
cpanm Cpanel::JSON::XS@4.41

# Verify the installed version
perl -MCpanel::JSON::XS -e 'print $Cpanel::JSON::XS::VERSION, "\n"'

# Optional: strip a UTF-8 BOM before decoding as a temporary workaround
perl -e 'use Cpanel::JSON::XS; my $in = shift; $in =~ s/^\\xEF\\xBB\\xBF//; print decode_json($in);'

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

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

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.