CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-G7M4-839X-CH6V

GHSA-g7m4-839x-ch6v: Denial of Service via Unbounded Digits Parameter in spomky-labs/otphp

Alon Barad
Alon Barad
Software Engineer

Jun 19, 2026·7 min read·2 visits

Executive Summary (TL;DR)

Unbounded digits parameter in otphp provisioning URIs triggers a float-to-integer conversion overflow, culminating in an unhandled division-by-zero fatal crash in PHP.

The spomky-labs/otphp library prior to version 11.4.3 is vulnerable to an unhandled DivisionByZeroError crash when parsing provisioning URIs containing a digits parameter value equal to or greater than 40. This allows unauthenticated remote attackers to trigger a Denial of Service by supplying a crafted URI, which causes float-to-integer cast overflow and subsequent division-by-zero fatal error in modern PHP runtimes.

Vulnerability Overview

The spomky-labs/otphp library is a widely used PHP implementation for generating and validating One-Time Passwords (OTPs) conforming to HOTP (RFC 4226) and TOTP (RFC 6238) specifications. The core library supports loading provisioning configurations via URIs using the otpauth:// scheme. Security teams frequently expose this parsing capability to external consumers to support user enrollment and authenticator registration flows.\n\nThe vulnerability, identified as GHSA-g7m4-839x-ch6v, stems from improper input validation of the digits parameter extracted from these provisioning URIs. The library fails to enforce an upper-bound sanity check on this parameter, allowing arbitrary integers to pass through. When the library subsequently attempts to generate or verify a passcode, the excessively large value triggers a fatal runtime crash.\n\nThis flaw allows unauthenticated remote attackers to initiate a Denial of Service (DoS) attack. By supplying a specially crafted URI to endpoints that ingest or validate authenticator profiles, the attacker triggers an unhandled DivisionByZeroError in modern PHP execution environments. This error halts the processing thread, bypassing typical catch blocks that target standard exceptions.

Root Cause Analysis

The vulnerability is categorized under CWE-1284 (Improper Validation of Specified Quantity in Input) and CWE-369 (Divide By Zero). The architectural flaw resides in how spomky-labs/otphp processes and validates configuration parameters during initialization. Specifically, the callback responsible for verifying the digits configuration parameter only implements a lower-bound check, ensuring that the value is strictly greater than zero.\n\nDuring OTP generation or verification, the library calculates the truncated OTP code using a modulo operation. The divisor is determined by evaluating 10 ** $digits to scale the output to the requested length. On standard 64-bit PHP 8.x runtimes, the maximum representable signed integer is 9223372036854775807 (approximately 9.22 * 10^18).\n\nWhen a value of 40 or higher is supplied to the digits parameter, the exponentiation operation 10 ** 40 evaluates to a floating-point representation because it exceeds the capacity of a standard 64-bit integer. PHP then attempts to cast this float back into an integer to satisfy the modulo (%) operator. Due to float-to-integer conversion overflow behavior in PHP, this cast yields 0 on 64-bit architectures.\n\nmermaid\ngraph LR\n A["Input URI with digits=50"] --> B["Factory::loadFromProvisioningUri()"]\n B --> C["Parameter check: 50 > 0 (Passes)"]\n C --> D["Modulo calculation: $code % (10 ** 50)"]\n D --> E["PHP converts 1.0e50 to Integer (Overflows to 0)"]\n E --> F["Evaluation: $code % 0"]\n F --> G["Fatal: DivisionByZeroError"]\n\n\nThe resulting calculation simplifies to $code % 0. In PHP 8.x, division or modulo by zero raises a fatal DivisionByZeroError object, which inherits from the Error class instead of the standard Exception class. This execution behavior terminates the thread immediately unless explicitly handled by a \Throwable block.

Code Analysis & Patch Assessment

Examining the vulnerable code path clarifies how the input validation mechanism is bypassed. In the OTP.php implementation, the digits parameter is registered with a validation closure that does not enforce an upper boundary.\n\nphp\n// Vulnerable parameter validation in OTP.php\nprotected function filterDigits(int $digits): void\n{\n // Missing upper-bound validation\n if ($digits <= 0) {\n throw new InvalidArgumentException("Digits must be greater than 0");\n }\n}\n\n\nWhen calculating the code value in OTP.php, the library executes the modulo operation using the value configured through the filterDigits function. The calculation proceeds as follows:\n\nphp\n// Vulnerable generation logic in OTP.php\npublic function at(int $timestamp): string\n{\n // ... calculation of binary code ...\n $digits = $this->getDigits();\n // If $digits is 50, (10 ** 50) is cast to int during % operation\n // (int)(10 ** 50) evaluates to 0 in PHP 8.x on 64-bit systems\n $otp = $code % (10 ** $digits);\n return str_pad((string)$otp, $digits, '0', STR_PAD_LEFT);\n}\n\n\nThe patch implemented in version 11.4.3 corrects this validation gap. It introduces a secondary check that enforces standard OTP bounds on the digits parameter, restricting the input to an acceptable range (such as between 1 and 10, or conforming strictly to standard MFA parameters).\n\nphp\n// Patched parameter validation in OTP.php\nprotected function filterDigits(int $digits): void\n{\n // Check both lower and upper bounds to prevent integer cast overflow\n if ($digits <= 0 || $digits > 10) {\n throw new InvalidArgumentException("Digits must be between 1 and 10");\n }\n}\n\n\nThis corrective action successfully resolves the vulnerability. By checking the boundary during instantiation rather than waiting for execution, any attempt to parse an invalid provisioning URI throws a catchable InvalidArgumentException before the modulo operation can occur.

Exploitation & Attack Vector Analysis

Exploitation of this vulnerability requires minimal attacker effort and does not rely on authentication or specific privilege levels. The attack surface consists of any application endpoint that accepts and parses user-supplied OTP configurations. This pattern is commonly observed in profile administration portals, multi-factor authentication registration endpoints, and administrator tools that import authentication records.\n\nTo execute the attack, the adversary constructs a valid provisioning URI containing a high digits query parameter value. A value of 50 is sufficient to trigger the overflow on standard x86-64 platforms. The attacker then submits this string directly to the target parsing interface, as represented in the payload below:\n\ntext\notpauth://totp/TargetSystem:user@example.com?secret=JBSWY3DPEHPK3PXP&digits=50\n\n\nWhen the system receives the request, it initiates the parser. The parser successfully constructs the OTP instance because the validation check accepts 50 as a positive integer. The crash is deferred until the application attempts to execute an action on the object, such as generating a test code for verification.\n\nOnce the verification routine triggers $otp->at(time()), the runtime environment halts execution. Because the application logic typically captures generic exceptions rather than throwables, the fatal error escalates to the web server or container worker. This terminates the process, causing a direct application-level denial of service.

Impact Assessment

The potential impact of GHSA-g7m4-839x-ch6v is classified as High (CVSS v4.0 score of 8.7). Because the flaw triggers a fatal engine crash, it can be abused to disable authentication systems or bring down worker processes processing queues containing the malicious URI.\n\nIn many modern PHP configurations (such as FPM or worker queues), a single unhandled fatal error terminates the worker process. While process managers (such as systemd or Kubernetes pods) automatically restart these processes, a persistent stream of malicious requests can exhaust available workers. This results in server-wide denial of service, rendering other unrelated application paths unresponsive.\n\nThe vulnerability does not allow remote code execution (RCE) or information disclosure, as the runtime terminates immediately without exposing memory content. However, the ease of exploitation makes this a significant availability risk. Security teams should prioritize remediating this issue, particularly in applications where MFA setup endpoints are exposed to unauthenticated public registrants.

Remediation & Detection Guidance

The primary remediation strategy is upgrading the spomky-labs/otphp dependency to version 11.4.3 or later. This release introduces strict constraints on parameter ranges, ensuring that arbitrary input cannot trigger mathematical overflows. Organizations should update their Composer environments by running composer update spomky-labs/otphp.\n\nIf upgrading is not immediately possible, security teams can implement an input validation filter. This filter parses and validates the digits parameter before handing it over to the library. If the value exceeds standard limits (e.g., greater than 10 or less than 4), the application should reject the payload:\n\nphp\n// Temporary pre-parsing validation logic\n$uri = $_POST['uri'];\n$query = parse_url($uri, PHP_URL_QUERY);\nif ($query !== null) {\n parse_str($query, $params);\n if (isset($params['digits']) && ((int)$params['digits'] < 4 || (int)$params['digits'] > 10)) {\n throw new InvalidArgumentException('Invalid digits parameter.');\n }\n}\n\n\nAdditionally, developers must review error handling structures throughout the application. When invoking methods on untrusted input, code blocks should catch \Throwable instead of \Exception to prevent unhandled fatal engine errors from terminating the thread:\n\nphp\ntry {\n $otp = OTPHP\Factory::loadFromProvisioningUri($uri);\n $otp->verify($code);\n} catch (\Throwable $t) {\n // Log error securely and prevent application crash\n Log::error('OTP Parsing failed: ' . $t->getMessage());\n return false;\n}\n

Technical Appendix

CVSS Score
8.7/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

Affected Systems

spomky-labs/otphp

Affected Versions Detail

Product
Affected Versions
Fixed Version
spomky-labs/otphp
Spomky-Labs
< 11.4.311.4.3
AttributeDetail
CWE IDCWE-1284 / CWE-369
Attack VectorNetwork (AV:N)
CVSS Score8.7
EPSS ScoreNot Mapped (No CVE)
ImpactDenial of Service (Availability: High)
Exploit StatusProof-of-Concept (PoC) Released
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499.004Endpoint Denial of Service: Application Exploitation
Denial of Service
CWE-1284
Improper Validation of Specified Quantity in Input

The product does not validate or incorrectly validates the input value, allowing values that are outside the expected range.

Known Exploits & Detection

GitHub Security AdvisoryOfficial advisory detailing the DivisionByZeroError vulnerability and containing a functional PHP Proof of Concept.

References & Sources

  • [1]Unbounded digits parameter in a provisioning URI triggers an uncaught DivisionByZeroError in OTP generation
  • [2]GitHub Advisory Database Record for GHSA-g7m4-839x-ch6v

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•4 minutes ago•CVE-2026-53865
7.2

CVE-2026-53865: Arbitrary Local Command Execution in OpenClaw via Untrusted Search Path

A critical untrusted search path vulnerability (CWE-426) exists in OpenClaw, an open-source, multi-platform personal AI assistant. In versions prior to 2026.5.2 (and up to 2026.5.26 in specific deployment configurations), the application merges workspace-derived configuration parameters into the operating system environment object. When executing administrative maintenance routines, OpenClaw invokes external system commands, such as the 'trash' utility, without verifying the underlying executable path. This allows a low-privileged local user or workspace collaborator to hijack binary execution flows, resulting in arbitrary command execution within the privilege context of the OpenClaw service wrapper.

Amit Schendel
Amit Schendel
0 views•6 min read
•32 minutes ago•CVE-2026-53852
5.4

CVE-2026-53852: Scope Containment Bypass in OpenClaw Device Re-pairing

OpenClaw versions prior to 2026.4.25 are subject to a scope containment bypass vulnerability in the device re-pairing component. When processing re-pairing requests, the application backend fails securely, allowing authenticated operators to bypass authorization containment policies. By submitting a re-pairing payload with an empty or omitted scope array, an operator can skip containment checks and retain broader, previously established administrative privileges. This vulnerability is classified under CWE-636: Not Failing Securely ('Failing Open').

Amit Schendel
Amit Schendel
1 views•8 min read
•about 1 hour ago•CVE-2026-53854
6.0

CVE-2026-53854: Privilege Escalation via Wildcard Authorization Inheritance in OpenClaw

CVE-2026-53854 is an authorization bypass vulnerability in OpenClaw, an open-source WhatsApp gateway CLI and Pi RPC agent. The flaw exists in the command authentication flow where low-privilege actors communicating via internal or webchat interfaces inherit global wildcard authorization states across channel boundaries. This cross-channel inheritance allows unauthorized command execution with administrative privileges.

Amit Schendel
Amit Schendel
2 views•5 min read
•about 2 hours ago•CVE-2026-0755
9.8

CVE-2026-0755: Remote Code Execution and Arbitrary File Exfiltration in gemini-mcp-tool

CVE-2026-0755 is a critical vulnerability in gemini-mcp-tool (<= 1.1.5) that allows unauthenticated remote code execution on Windows installations and arbitrary local file exfiltration across all supported operating systems. The flaws exist within the execAsync command runner and the input handling logic of the Model Context Protocol (MCP) server, which fails to securely escape arguments passed to Node.js child processes and does not validate local file references in user-supplied prompt strings.

Alon Barad
Alon Barad
2 views•7 min read
•about 3 hours ago•GHSA-2JX3-65F3-XR8R
5.3

GHSA-2JX3-65F3-XR8R: Dynamic Property Injection (Mass Assignment) in spomky-labs/otphp

A critical mass-assignment (property injection) vulnerability exists in the PHP One-Time Password (OTP) library spomky-labs/otphp within the Factory::loadFromProvisioningUri method. When an application loads an OTP provisioning URI (such as a QR code configuration link), a hostile URI can inject query parameters that dynamically overwrite internal, private, or read-only object properties of the OTP instance. This behavior leads to application state corruption, validation bypasses, or uncaught TypeErrors that crash the executing application process.

Amit Schendel
Amit Schendel
3 views•7 min read
•about 4 hours ago•GHSA-6VVH-PXR4-25R7
5.9

GHSA-6vvh-pxr4-25r7: Cryptographic Integrity Degradation in JWT Framework ChaCha20-Poly1305 Key Encryption

An implementation flaw in the experimental Chacha20Poly1305 key-encryption algorithm within the PHP JWT Framework (web-token/jwt-framework) discards the Poly1305 authentication tag during key wrapping and omits it during decryption. This degrades the Authenticated Encryption with Associated Data (AEAD) protection to unauthenticated ChaCha20, allowing an attacker to manipulate the encrypted Content Encryption Key (CEK) without detection.

Amit Schendel
Amit Schendel
4 views•7 min read