Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
hyperswitch-unsigned-webhook — Proof-of-concept for an unauthenticated Hyperswitch Worldpayxml webhook flaw (CWE-345/306) that forges SETTLED XML to mark payments succeeded without PSP capture. | Kitploit
Tools/GitHubGitHub/abraxas/hyperswitch-unsigned-webhook
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingAuthenticationLabs & Practice
GitHubabraxas/hyperswitch-unsigned-webhook

hyperswitch-unsigned-webhook

Proof-of-concept for an unauthenticated Hyperswitch Worldpayxml webhook flaw (CWE-345/306) that forges SETTLED XML to mark payments succeeded without PSP capture.

View Repository
715 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Abraxas Labs - hyperswitch-unsigned-webhook

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  hyperswitch-unsigned-webhook

hyperswitch-unsigned-webhook

Hyperswitch 2026.09.21.0 - Juspay

Worldpayxml::verify_webhook_source returns Ok(true) with a comment that verification is done via mTLS. There is no mTLS on this route. The function ignores the body and the headers. incoming.rs then trusts source_verified and takes HandleResponse with no PSync. LastEvent::Settled maps to PaymentIntentSuccess. The default IncomingWebhook algorithm is NoAlgorithm. BitPay and Shift4 inherit that. Worldpayxml does not even get that far. It short-circuits.

Unauthenticated dummy SETTLED XML marks the payment succeeded. No Worldpay capture. No client cert.

IDno CVE yet
CWECWE-345, CWE-306
CVSSHigh: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
ProductHyperswitch
Affectedthrough 2026.09.21.0 Worldpayxml inbound webhooks
Authunauthenticated; need merchant_id and orderCode
LicenseGNU Affero GPL v3.0
Lab127.0.0.1 only

What an attacker can do

Need merchant_id (in every Hyperswitch dashboard URL) and orderCode equal to the attempt's connector_transaction_id. POST /webhooks/{merchant_id}/worldpayxml unsigned SETTLED. If source_verified were false, incoming would Trigger and PSync the connector. Worldpayxml never takes that path. Intent goes Charged. Lab: status=succeeded. Dummy XML. No PSP.

Guessing payment ids is not the bug. Forging SETTLED for an id you already saw is. Not a shell. Not a live Worldpay settlement.

Same product, different bug: payout confirm unbound client_secret.

How I found it

I read Ok(true), then HandleResponse vs Trigger, then Settled -> PaymentIntentSuccess. The comment says mTLS. The lab POST has no client cert.

The first client that looks at this will POST the webhook against requires_confirmation. Incoming will not Charged a payment that has not left confirmation. Stamp the attempt, or wait until requires_capture / processing. Lab does the stamp. That stamp is a lab fixture. A live attempt already has the connector id. The webhook does not.

Wrong turns already recorded: signed HMAC on a connector that actually verifies (this path does not); treating webhook HTTP 200 as the oracle (poll GET /payments/{id} until status=succeeded); orderCode that is not connector_transaction_id; a reverse shell. Theatre.

Then: merchant, API key, worldpayxml MCA, payment with confirm=false, stamp connector_transaction_id, unsigned SETTLED, retrieve.

Lab

cd lab
./run.sh

Target only http://127.0.0.1:18082. run.sh clones tag 2026.09.21.0 into lab/hyperswitch-src for config and migrations.

IOC status_before=requires_confirmation
IOC webhook status=200 unsigned lastEvent=SETTLED
IOC poll status=succeeded
SUCCESS Hyperswitch unsigned Worldpayxml webhook Charged

The fix

Verify the Worldpay notify (signature / mTLS that the route actually terminates). Do not HandleResponse on a connector that returned Ok(true) from a no-op. Unsigned SETTLED must not move the intent to succeeded.

References

  • github.com/juspay/hyperswitch tag 2026.09.21.0
  • worldpayxml.rs · transformers.rs · incoming.rs · webhooks.rs · crypto.rs
  • Same product: hyperswitch-payout-confirm-secret
  • CWE-345 · CWE-306

License

GNU Affero GPL v3.0. See LICENSE. Loopback lab only. No warranty.

Download Tool