Skip to main content
Vulnerability Database/CVE-2026-58200

CVE-2026-58200: Payload Cloudinary Plugin Auth Bypass

CVE-2026-58200 is an authentication bypass flaw in Payload Cloudinary Plugin that allows authenticated users to generate unauthorized Cloudinary signatures for malicious operations. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-58200 Overview

CVE-2026-58200 is a signature verification weakness [CWE-347] in the @jhb.software/payload-cloudinary-plugin, a Cloudinary integration for Payload CMS. Versions from 0.3.0 through 0.3.x expose the POST /api/cloudinary-generate-signature endpoint when clientUploads is enabled. The handler in cloudinary/src/getGenerateSignature.ts forwards attacker-controlled body.paramsToSign directly to cloudinary.utils.api_sign_request. No key allowlist, collection policy, timestamp freshness check, or folder enforcement is applied. Any authenticated Payload user can obtain a valid Cloudinary HMAC-SHA1 signature for arbitrary parameters. The issue is fixed in version 0.4.0.

Critical Impact

Authenticated users can turn the signature endpoint into a signing oracle, enabling asset overwrite, uploads to arbitrary folders, callbacks to attacker URLs, and cache invalidation on the Cloudinary account.

Affected Products

  • @jhb.software/payload-cloudinary-plugin version 0.3.0
  • @jhb.software/payload-cloudinary-plugin versions 0.3.x prior to 0.4.0
  • Payload CMS deployments using this plugin with clientUploads enabled

Discovery Timeline

  • 2026-09-15 - CVE-2026-58200 published to NVD
  • 2026-09-15 - Last updated in NVD database

Technical Details for CVE-2026-58200

Vulnerability Analysis

The plugin exposes a server-side endpoint intended to sign a narrow set of upload parameters for browser-based Cloudinary uploads. In vulnerable releases, the handler accepts an arbitrary paramsToSign object from the authenticated request body and signs whatever is provided. Because the client-facing Cloudinary API key is by design visible to the browser, the missing server-side restrictions are the only barrier to unauthorized operations. A returned HMAC-SHA1 signature is sufficient to authorize Cloudinary API calls whose parameters were signed.

With control over paramsToSign, an attacker can request signatures for overwrite, type, notification_url, invalidate, folder, and public_id. This authorizes asset replacement at chosen public_id values, uploads outside the configured folder, changes to upload visibility, callbacks to attacker-selected URLs, and cache invalidation.

Root Cause

The endpoint lacks four controls: a parameter allowlist, a per-collection access check, a timestamp freshness window, and enforcement that the signed folder matches the configured folder. The default access function returned !!req.user, which authorizes any logged-in user regardless of their ability to create documents in the target collection.

Attack Vector

An authenticated Payload user sends a POST request to /api/cloudinary-generate-signature with a crafted paramsToSign body. The server returns a valid signature. The attacker then submits an upload directly to Cloudinary using that signature, the visible API key, and the malicious parameters.

typescript
// Patch excerpt: cloudinary/src/getGenerateSignature.ts
     req: PayloadRequest
   }) => boolean | Promise<boolean>
   apiSecret: string
+  /** Slugs of the collections this plugin manages. Signatures may only be requested for these. */
+  collections: string[]
+  /** The configured upload folder. When set, the signed `folder` parameter must match it. */
+  folder?: string
 }

-const defaultAccess: Args['access'] = ({ req }) => !!req.user
+/**
+ * By default a user may only request a signature if they are allowed to create
+ * documents in the target upload collection. Falling back to mere authentication
+ * would let any logged-in user mint signatures for collections they cannot upload to.
+ */
+const defaultAccess: Args['access'] = async ({ collectionSlug, req }) => {
+  const createAccess = req.payload?.collections?.[collectionSlug]?.config?.access?.create
+  if (!createAccess) {
+    return !!req.user
+  }
+  return Boolean(await createAccess({ data: {}, req }))
+}
+
+/** Reject signatures whose timestamp is too far from now to limit replay. */
+const maxTimestampSkewSeconds = 60 * 60

Source: GitHub Commit da232590

Detection Methods for CVE-2026-58200

Indicators of Compromise

  • Cloudinary asset overwrites at existing public_id values not initiated by legitimate editors.
  • Uploaded assets located outside the plugin's configured folder.
  • Cloudinary notification_url callbacks reaching external domains not owned by the operator.
  • Unexpected cache invalidation events on the Cloudinary account.

Detection Strategies

  • Inspect application logs for POST /api/cloudinary-generate-signature requests containing parameters beyond timestamp, folder, and public_id.
  • Correlate authenticated Payload sessions with the frequency of signature requests to surface abnormal signing activity.
  • Compare Cloudinary upload metadata (folder, public_id, notification_url) against the plugin's configured folder allowlist.

Monitoring Recommendations

  • Enable Cloudinary audit logs and alert on overwrite=true, invalidate=true, or non-empty notification_url values.
  • Track the ratio of signature requests to actual upload completions for anomaly detection.
  • Forward Payload CMS access and API logs into a central analytics platform for retention and correlation.

How to Mitigate CVE-2026-58200

Immediate Actions Required

  • Upgrade @jhb.software/payload-cloudinary-plugin to version 0.4.0 or later.
  • Rotate the Cloudinary API secret used by the plugin to invalidate any signatures obtained during exposure.
  • Audit Cloudinary asset inventory for unexpected public_id overwrites and out-of-folder uploads.
  • Review Payload user accounts and disable any that should not have upload rights.

Patch Information

The fix is delivered in GitHub Release cloudinary@0.4.0 via Pull Request #155 and commit da232590. The patched handler restricts signable parameters to an allowlist, enforces per-collection create access, checks timestamp freshness within a 60-minute window, and validates the signed folder against the configured folder. See the GitHub Security Advisory GHSA-h5x8-xp6m-x6q4 for advisory details.

Workarounds

  • Disable clientUploads in the plugin configuration and route uploads through server-side handlers until patched.
  • Provide a custom access function that verifies the caller has create permission on the target upload collection.
  • Restrict authenticated user access to the /api/cloudinary-generate-signature route with a reverse proxy or web application firewall.
bash
# Upgrade to the patched release
npm install @jhb.software/payload-cloudinary-plugin@0.4.0

# Verify installed version
npm ls @jhb.software/payload-cloudinary-plugin

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

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.