T05 · Unauthorized Access and Privilege Escalation
- Location
server-simple.ts:1143- Finding
HOT PAY Webhook Events Are Accepted Without Authentication
- Content
View full analysis
{ try { const payload = req.body; console.log('\n🔔 HOT PAY Webhook Received'); console.log('='.repeat(70)); console.log(JSON.stringify(payload, null, 2)); console.log('='.repeat(70)); if (payload.type === 'PAYMENT_STATUS_UPDATE' && payload.status === 'SUCCESS') { console.log(`✅ Payment Confirmed!`); console.log(` Item ID: ${payload.item_id}`); console.log(` Amount: $${payload.amount_float} (${payload.amount_usd} USD)`); console.log(` Memo: ${payload.memo || 'N/A'}`); console.log(` TX Hash: ${payload.near_trx}`); console.log(` Verify: https://nearblocks.io/txns/${payload.near_trx}`); } res.status(200).json({ received: true }); } catch (error: any) { console.error('❌ Webhook Error:', error.message); res.status(500).json({ error: 'Webhook processing failed' }); } }); ``` ### Technical Analysis The webhook endpoint trusts arbitrary JSON without verifying a provider signature, shared secret, timestamp, event identifier, transaction status, or replay state. Any party that can access the public tunnel can submit an object containing `type: "PAYMENT_STATUS_UPDATE"` and `status: "SUCCESS"`, causing it to be treated as a confirmed payment. This contradicts the webhook signature-verification claim in `SKILL.md:290`. Although the current handler primarily logs the event, it establishes an unsafe payment-confirmation boundary and would become directly exploitable for unauthorized fulfillment if business logic were subsequently attached. ### Attack Path 1. The operator starts the Skill and exposes it through the localhost.run tunnel. 2. An attacker obtains or guesses the public tunnel URL. 3. The ...[truncated 846 chars]- Remediation
View remediation
