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-H5X8-XP6M-X6Q4

GHSA-H5X8-XP6M-X6Q4: Unvalidated Signature Generation in @jhb.software/payload-cloudinary-plugin

Alon Barad
Alon Barad
Software Engineer

Jun 20, 2026·6 min read·9 visits

Executive Summary (TL;DR)

The @jhb.software/payload-cloudinary-plugin fails to validate client-supplied parameters passed to Cloudinary's cryptographic signing helper. Authenticated users can obtain mathematically valid HMAC-SHA1 signatures for any arbitrary payload, creating a signature oracle to overwrite files, bypass visibility rules, or trigger outbound SSRF webhooks.

The @jhb.software/payload-cloudinary-plugin exposes an endpoint that performs unvalidated cryptographic signing of Cloudinary API parameters, allowing authenticated users with minimal privileges to forge valid signatures for arbitrary actions. This flaw allows attackers to overwrite remote storage assets, execute unauthorized file uploads, alter asset visibility parameters, trigger SSRF webhooks, and perform directory traversal within Cloudinary repositories.

Vulnerability Overview

The module @jhb.software/payload-cloudinary-plugin integrates Cloudinary cloud storage within Payload CMS architectures. When configured with client-side direct uploads enabled (clientUploads: true), the application registers a dedicated backend route designed to handle request signing. This design optimizes payload delivery by transferring large binary media uploads directly from the client browser to Cloudinary's infrastructure, reducing CPU usage and bandwidth consumption on the primary application server.\n\nBecause direct client-side uploads require authentication, Cloudinary relies on cryptographic signatures generated with a private API secret key. The plugin mounts a server-side route designed to accept upload parameters from clients, compute the corresponding HMAC-SHA1 signature, and return it to the browser. However, the endpoint acts as an unrestricted signing oracle because it lacks input sanitization, key whitelisting, or parameter verification mechanisms.\n\nAny user possessing a valid, low-privilege authentication token for the Payload CMS instance can make requests to this signing endpoint. By supplying arbitrary parameter blocks, the client forces the server to return valid cryptographic signatures. This interaction enables unauthorized asset modification, access-control subversion, and Server-Side Request Forgery within the context of the associated Cloudinary subscription.

Root Cause Analysis

The cryptographic security model of Cloudinary requires that upload payloads match a specific signature generated via the API_SECRET token. The signature calculation sorts the designated keys in alphabetical order, concatenates key-value pairs with ampersands, appends the secret token, and executes an SHA-1 hashing algorithm. Because the secret key must remain hidden from client-side runtime environments, the server is tasked with acting as a trusted helper to perform signature creation.\n\nIn vulnerable versions of the plugin, specifically up to version 0.3.4, the implementation in cloudinary/src/getGenerateSignature.ts fails to validate the keys contained in the request. The application registers the HTTP POST endpoint /api/cloudinary-generate-signature and binds it to a handler that reads the JSON payload directly. It parses the object named paramsToSign provided in the HTTP request body and transfers it directly to the native Cloudinary SDK utility helper.\n\nThe vulnerable sink is found at line 55 of getGenerateSignature.ts, where the application executes cloudinary.utils.api_sign_request(body.paramsToSign, apiSecret). Because there is no schema enforcement or restriction on the dictionary keys, the server signs any values submitted by the client. The absence of validation checks means parameter injection is trivially accomplished, breaking the security boundary between client and server.

Code Analysis

An analysis of the source code changes between the vulnerable and patched versions reveals the exact mechanism of the flaw and its remediation. In the vulnerable codebase, the handler parses the request body and processes the parameters without checking for malicious inputs or unauthorized keys:\n\ntypescript\n// Vulnerable Implementation in getGenerateSignature.ts\nconst body = await req.json?.()\nconst signature = cloudinary.utils.api_sign_request(body.paramsToSign, apiSecret)\n\n\nIn contrast, the patched version introduces a strict validation pattern to protect the signature generation flow. The update restricts input keys, validates the format of fields, and blocks structural traversal attempts:\n\ntypescript\n// Patched Implementation in getGenerateSignature.ts\nconst paramsToSign = body.paramsToSign as Record<string, unknown>\nconst allowedKeys = new Set(['timestamp', 'folder', 'public_id'])\nif (\n !paramsToSign ||\n Object.keys(paramsToSign).some((key) => !allowedKeys.has(key)) ||\n typeof paramsToSign.timestamp !== 'string'\n) {\n throw new Forbidden()\n}\nif (folder && paramsToSign.folder !== folder.replace(/^\/|\/$/g, '')) {\n throw new Forbidden()\n}\nif (\n typeof paramsToSign.public_id === 'string' &&\n (paramsToSign.public_id.includes('..') || paramsToSign.public_id.startsWith('/'))\n) {\n throw new Forbidden()\n}\nconst signature = cloudinary.utils.api_sign_request(paramsToSign, apiSecret)\n\n\nThe patch enforces strict security controls: first, it checks incoming parameters against an allowed whitelist of timestamp, folder, and public_id, rejecting any unexpected options. Second, it requires the timestamp to be a string value. Third, it validates the folder parameter against the plugin config, preventing directory manipulation. Fourth, it blocks path-traversal strings like .. and root-relative prefix symbols / within public_id parameters. This blocks attempts to access directories outside of the configured folder structure.

Exploitation Methodology

Exploiting this signature oracle requires an attacker to possess any valid, low-privilege authentication token for the target Payload CMS system. Since the default route-level authorization only validates session existence (!!req.user), an authenticated guest or low-privilege editor can access the endpoint. The attacker must also retrieve the public Cloudinary parameters, such as the api_key and cloud_name, which are exposed to the client by design in index.ts to facilitate uploads.\n\nThe attacker sends a structured HTTP POST request to /api/cloudinary-generate-signature containing their desired target parameters inside the paramsToSign property. To overwrite an existing asset, the attacker generates an exploit payload containing overwrite=true, the targeted file's public_id, and a current unix timestamp. The backend server signs this payload and returns the valid HMAC-SHA1 signature.\n\nWith the generated signature, the attacker bypasses the application server entirely and transmits the forged payload directly to Cloudinary's API. The remote storage provider validates the signature against its own cryptographic keys, accepts the request, and overwrites the specified high-value media file. The automated Python script in this report demonstrates how to perform these operations, verifying that returned signatures match the expected cryptographic format.

Impact Assessment

The security implications of an unrestricted signature oracle on a Cloudinary account are extensive. Integrity is compromised because an attacker can overwrite arbitrary media files, which can lead to web application defacement, malicious file distribution, or database corruption if media metadata is parsed dynamically. This allows attackers to replace legitimate assets with spoofed or exploit-carrying files.\n\nFurthermore, the vulnerability introduces a network-level Server-Side Request Forgery risk. An attacker can request a signature that includes the notification_url parameter, pointing to a server under their control. When Cloudinary completes an upload transaction, its backend servers will make an outbound HTTP POST request to the attacker's server, leaking internal file-processing data or metadata.\n\nAdditionally, attackers can perform directory traversal attacks and invalidate CDN caches. By combining path-traversal sequences in the folder parameter with the invalidate=true option, an attacker can delete cached media resources from global CDN edge caches. This can increase administrative costs and degrade application performance, leading to a denial of service.

Remediation & Defensive Strategies

To remediate this vulnerability, system administrators and developers must upgrade @jhb.software/payload-cloudinary-plugin to version 0.4.0 or higher. This update introduces the parameter validation and path-filtering controls necessary to secure the signing endpoint. After updating, verify that configuration values for default storage paths are correctly populated in the plugin's initialization block.\n\nIf an immediate package upgrade is not feasible, client-side uploads can be disabled by setting clientUploads: false in the plugin's configuration options. This forces all media uploads to process directly through the Payload CMS backend, eliminating the risk associated with the signature generation endpoint. While this increases server bandwidth and processing load, it removes the attack surface.\n\nWeb Application Firewalls can also be configured to block malicious requests targeting this vulnerability. Define rules to monitor POST requests directed to /api/cloudinary-generate-signature and block payloads containing unauthorized parameters such as overwrite, notification_url, invalidate, or directory-traversal characters in the paramsToSign block. This provides defense-in-depth while the application is being upgraded.

Official Patches

jhb-softwareSource repository containing fix updates for version 0.4.0.

Technical Appendix

CVSS Score
7.1/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L

Affected Systems

Systems deploying @jhb.software/payload-cloudinary-plugin versions between 0.3.0 and 0.4.0 with clientUploads enabled.

Affected Versions Detail

Product
Affected Versions
Fixed Version
@jhb.software/payload-cloudinary-plugin
jhb-software
>= 0.3.0 < 0.4.00.4.0
AttributeDetail
CWE IDCWE-347 (Improper Verification of Cryptographic Signature)
Attack VectorNetwork (Unauthenticated or Low-Privilege authenticated API interaction)
CVSS Score7.1 (High)
ImpactIntegrity Loss, Server-Side Request Forgery, Directory Traversal, CDN Invalidation
Exploit StatusProof-of-Concept Available
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1553Subvert Trust Controls
Defense Evasion
T1020Automated Exfiltration
Exfiltration
T1102Web Service
Command and Control
CWE-347
Improper Verification of Cryptographic Signature

The software does not verify or incorrectly verifies the cryptographic signature for data.

Known Exploits & Detection

GitHub Security AdvisoryAdvisory containing technical description and proof of concept parameters.

References & Sources

  • [1]GHSA-H5X8-XP6M-X6Q4 Security Advisory
  • [2]Software Package GitHub Repository
  • [3]OSV Database Entry

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

•28 minutes ago•CVE-2026-16729
4.8

CVE-2026-16729: Cookie Attribute Injection in Undici via Unsanitized Domain and Unparsed Fields

CVE-2026-16729 (GHSA-v3r7-h72x-cjcm) is a medium-severity cookie attribute injection vulnerability in Undici's web-compliant cookie utility module. Due to insufficient validation of domain parameters and raw attributes in the unparsed options array, arbitrary attributes like SameSite, HttpOnly, and Secure can be injected. This allows attackers to bypass CSRF protections, strip security flags, or override intended cookie behaviors when applications pass user-controlled values to these properties.

Amit Schendel
Amit Schendel
0 views•7 min read
•about 1 hour ago•CVE-2026-14643
5.9

CVE-2026-14643: Shared Cache Pollution and Information Disclosure via Whitespace Parsing Discrepancies in Undici

An interpretation conflict (CWE-436) in the cache interceptor of the undici HTTP client for Node.js causes whitespace-padded Cache-Control directives to be parsed incorrectly, leading to shared cache pollution and the unauthorized disclosure of sensitive, private, or authenticated user information (CWE-524).

Amit Schendel
Amit Schendel
1 views•6 min read
•about 2 hours ago•CVE-2026-15157
4.2

CVE-2026-15157: CRLF Injection in undici HTTP/1.1 Dispatcher

CVE-2026-15157 details an improper neutralization of CRLF sequences ('CRLF Injection') within undici, a widely used Node.js HTTP/1.1 client. The vulnerability is triggered when processing request bodies that exhibit a duck-typed blob-like interface. When an application accepts untrusted data and assigns it to the .type property of such an object without setting an explicit Content-Type on the request, undici appends the value directly to the outgoing headers array without validating it against control characters. This allows remote attackers to inject carriage return and line feed sequences, culminating in arbitrary header injection, HTTP response splitting, or HTTP request smuggling.

Alon Barad
Alon Barad
3 views•6 min read
•about 3 hours ago•CVE-2026-54272
6.9

CVE-2026-54272: SSRF and Trust-Boundary Bypass via Input Misclassification in ip-address Library

A trust-boundary bypass and Server-Side Request Forgery (SSRF) vulnerability exists in the ip-address library versions 10.1.1 through 10.2.0 due to structural input misclassification. The library fails to resolve and normalize transition IP notations, such as IPv4-mapped IPv6 (::ffff:0:0/96) and NAT64 (64:ff9b::/96) addresses, to their embedded IPv4 representations prior to evaluation. Consequently, standard security validation checks (e.g., isLoopback, isLinkLocal, isULA) return false for these addresses. This allows remote attackers to bypass application-level IP address filters, gaining unauthorized access to internal resources, cloud metadata interfaces, and local services on dual-stack hosts or environments utilizing NAT64 gateways.

Amit Schendel
Amit Schendel
2 views•7 min read
•about 4 hours ago•CVE-2026-18574
9.3

CVE-2026-18574: Authentication Bypass via Alternate Path in Check Point Security Management Server

A critical authentication bypass vulnerability (CVE-2026-18574) in Check Point Security Management and Multi-Domain Security Management (MDS) Servers allows unauthenticated remote attackers to execute arbitrary system commands with administrative privileges. The flaw stems from an alternate path authentication bypass (CWE-288) in the management interface daemons.

Amit Schendel
Amit Schendel
8 views•6 min read
•about 4 hours ago•CVE-2026-69198
6.9

CVE-2026-69198: Server-Side Request Forgery Bypass via CIDR Suffix in ip-address Library

An input validation vulnerability in the npm package `ip-address` allows unauthenticated remote attackers to bypass Server-Side Request Forgery (SSRF) protections by appending a `/0` CIDR suffix to IP address strings. This causes the library's classification helper functions to incorrectly identify internal addresses as public, external addresses, while normalization helpers resolve the address back to its internal form during network connection establishment.

Amit Schendel
Amit Schendel
3 views•6 min read