Skip to main content
CVE Vulnerability Database

CVE-2026-9537: Mojo::JWT Information Disclosure Flaw

CVE-2026-9537 is an information disclosure vulnerability in Mojo::JWT for Perl that enables timing attacks to forge tokens. This post covers the technical details, affected versions, security impact, and mitigation.

Published:

CVE-2026-9537 Overview

CVE-2026-9537 affects Mojo::JWT versions before 1.02, a Perl module used to encode and decode JSON Web Tokens (JWTs). The decode() method verifies HMAC signatures using Perl's eq operator, which performs a non-constant-time byte comparison. The comparison exits at the first differing byte, so verification time correlates with the number of matching leading bytes. An attacker who can submit tokens and measure response latency can aggregate timing measurements across many requests to reconstruct a valid signature and forge tokens. This is a classic timing side-channel vulnerability [CWE-208].

Critical Impact

Remote attackers can recover HMAC signatures through timing analysis and forge JWTs accepted by any application using Mojo::JWT prior to 1.02.

Affected Products

  • Mojo::JWT Perl module, all versions prior to 1.02
  • Perl applications and web services performing symmetric (HMAC) JWT verification through Mojo::JWT
  • Downstream distributions bundling CPAN's Mojo::JWT before the fixed release

Discovery Timeline

  • 2026-06-03 - Mojo::JWT1.02 released with fix for timing side-channel in symmetric signature verification
  • 2026-07-17 - CVE-2026-9537 published to NVD and disclosed on the OpenWall oss-security list
  • 2026-07-20 - Last updated in NVD database

Technical Details for CVE-2026-9537

Vulnerability Analysis

The vulnerability lies in the signature verification path of the decode() method in lib/Mojo/JWT.pm. When a token uses an HMAC algorithm such as HS256, HS384, or HS512, the module recomputes the expected HMAC over the token header and payload, then compares it against the signature supplied by the caller. The comparison uses Perl's eq string operator. eq is implemented as a byte-by-byte comparison that returns false as soon as it encounters a mismatched byte, meaning the total time spent in the comparison is proportional to the length of the shared prefix between the two strings.

An attacker who controls the signature portion of a submitted JWT can iterate through candidate signature bytes and measure server response time. Bytes that match the beginning of the expected HMAC cause the comparison loop to run longer than bytes that do not. By repeating measurements and averaging out network jitter, the attacker recovers the expected signature one byte at a time. Once the full signature is known, arbitrary tokens can be forged for the target claims. This is the same class of side-channel that motivated constant-time compare primitives such as hmac.compare_digest() in Python and hash_equals() in PHP.

Root Cause

The root cause is the absence of a constant-time comparison for a secret-dependent value. Signature bytes are effectively secret because they authenticate token integrity, so any early-exit comparison leaks information about them. The fix in version 1.02 introduces a constant-time comparison in the decode path so that verification time no longer depends on the position of the first differing byte.

Attack Vector

The attack is remote and unauthenticated wherever the application decodes attacker-supplied JWTs. The attacker submits large numbers of forged tokens, measures response timing, and statistically recovers each byte of the HMAC signature. Practical exploitation requires many requests and stable timing measurements, which limits it against low-latency, uniform-jitter targets but remains feasible against co-located services, containerized workloads, or endpoints where request timing is directly observable.

text
# Patch metadata from Mojo-JWT commit b8aefb846613e44b5b12bc170898ffd5b05094a2

Revision history for Perl module Mojo::JWT

+1.02 2026-06-03
+  - This release contains fixes for security issues, everybody should upgrade!
+  - Improved security of decode to prevent timing side-channel attacks in symmetric signatures
+
 1.01 2024-10-15
   - Fix non-portable test

Source: GitHub Patch Commit

text
# Version bump in lib/Mojo/JWT.pm accompanying the constant-time comparison fix

 use Mojo::Base -base;

-our $VERSION = '1.01';
+our $VERSION = '1.02';
 $VERSION = eval $VERSION;

 use Scalar::Util ();

Source: GitHub Patch Commit

Detection Methods for CVE-2026-9537

Indicators of Compromise

  • High volumes of JWT-bearing requests from a single source or narrow set of sources targeting the same account, tenant, or API endpoint
  • Sequences of requests with identical JWT headers and payloads but incrementally changing signature bytes
  • Repeated signature verification failed errors immediately followed by a successful token acceptance from the same client

Detection Strategies

  • Inventory Perl services and CPAN dependencies to identify any use of Mojo::JWT at a version below 1.02
  • Instrument JWT verification failures with structured logging that captures source IP, user-agent, and target claim so brute-force patterns become queryable
  • Alert on statistical anomalies in request rate against JWT-protected endpoints, especially requests that fail signature checks at high frequency

Monitoring Recommendations

  • Track failed-to-successful JWT verification ratios per client and flag sudden shifts that could indicate a signature-recovery attack in progress
  • Monitor response latency variance on token-accepting endpoints, since timing attacks often coincide with abnormally consistent, high-volume probing
  • Correlate authentication anomalies with subsequent privileged actions to identify potential post-forgery abuse of forged JWTs

How to Mitigate CVE-2026-9537

Immediate Actions Required

  • Upgrade Mojo::JWT to version 1.02 or later across all Perl applications, container images, and build pipelines
  • Rotate any HMAC signing secrets that may have been exposed to internet-facing services running the vulnerable module
  • Invalidate long-lived tokens issued under the previous secret to prevent replay of potentially forged JWTs

Patch Information

The fix is delivered in Mojo::JWT1.02, released on 2026-06-03. The patch replaces the vulnerable eq-based signature comparison in decode() with a constant-time comparison. Review the fix in the upstream repository via the GitHub Patch Commit and the coordination thread on the OpenWall OSS-Security Discussion.

Workarounds

  • Where an immediate upgrade is not possible, wrap Mojo::JWT->decode() in a caller that performs its own constant-time comparison of the recomputed HMAC before trusting the module's result
  • Apply strict rate limiting and request throttling on JWT-verifying endpoints to raise the cost of timing measurement attacks
  • Prefer asymmetric JWT algorithms such as RS256 or ES256 for externally exposed services until the symmetric verification path is patched
bash
# Upgrade Mojo::JWT to the fixed release using cpanm
cpanm Mojo::JWT@1.02

# Verify the installed version
perl -MMojo::JWT -E 'say $Mojo::JWT::VERSION'

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.