
Cloud Vulnerability DB
A community-led vulnerabilities database
Webhook verification hashes the data object as unencoded key=value pairs joined by &, with null and nested values coerced to strings, and performed no type or shape validation on the received payload. An attacker who already holds one validly signed webhook can derive a structurally different payload that verifies under the same signature, for example a different orderCode, or an object substituted for a string field.
| Ecosystem | Package | Affected | Patched |
|---|---|---|---|
| Packagist | payos/payos | <= 2.0.0 | 2.0.1 |
Low — CVSS 3.1 base score 3.7, CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
CWE-347 (Improper Verification of Cryptographic Signature), CWE-88.
The signed string is built by sorting the top-level keys of data and joining key=value with &, without encoding. Values null, undefined and the literal strings "null"/"undefined" all become empty, and nested objects are stringified (in JavaScript, to [object Object]). Because verification accepted any keys, any value types and any characters:
description and a signed (data, signature) pair is exposed, a value containing & and = can be re-split into different fields. This moves orderCode (or another field) to a different integer under the same HMAC.null and "null" hash identically.[object Object] can be replaced by an arbitrary JSON object.
Remote unauthenticated exploitation without a previously signed payload was not demonstrated.The legacy signing format is unchanged, so existing webhooks keep verifying. Before hashing, the SDK now validates the received data:
[A-Za-z0-9_];null, and must not contain =;Invalid webhook data. Unknown string fields are still accepted and remain covered by the signature.
A03 is partially mitigated for payment webhooks through required-field/type validation and rejection of delimiter-bearing values. Delimiter ambiguity remains possible for signatures over original values containing =. This release does not replace the legacy signing format or authenticate outer webhook metadata.
Known limitation. The legacy signing format maps null, an empty string and the literal strings "null" and "undefined" to the same value, so they share one signature. Someone holding a signed webhook can swap a text field between these values, for example description: "null" to description: "". Integer fields such as orderCode and amount, nested objects and values containing = are rejected, so no other change is possible this way. Removing this needs a new signing format; until then, confirm the order's status and amount through the payment-link API before fulfilling it.Upgrade. Until then, verify webhooks server-side only, and before fulfilling an order, confirm its status and amount through the payment-link API (GET /v2/payment-requests/{id}) instead of trusting webhook fields alone.
Vo Le Anh Tuan (Swinburne University of Technology), GitHub @tuankhongbietcode
Source: NVD
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."