BuidlZone-Labs/zicket-web

Unauthenticated Payment Reconciliation API Endpoint Allows Arbitrary Ticket Generation

Ouverte

#172 ouverte le 29 juil. 2026

 (9 commentaires) (0 réaction) (1 personne assignée)TypeScript (43 forks)auto 404
Stellar Wavedifficulty: mediumhelp wantedsecurity

Métriques du dépôt

Stars
 (4 étoiles)
Métriques de merge PR
 (Métriques PR en attente)

Description

Category

Security

Priority

Critical

Description

The payment reconciliation API endpoint /api/payments/reconcile/route.ts accepts client-provided JSON payloads containing isPaid: true and isConfirmed: true without performing any server-side authentication, signature verification, payment gateway webhook validation, or rate limiting. Any user or automated script can issue POST requests to mint valid ticket IDs without paying.

Evidence from app/api/payments/reconcile/route.ts#L40-L45:

if (!body.isConfirmed || !body.isPaid) {
  return NextResponse.json(
    { ok: false, error: "Payment is not yet fully confirmed." },
    { status: 409 },
  );
}

Proposed Solution

  1. Require server-side verification of payment gateway webhooks or on-chain transaction logs before issuing tickets.
  2. Add JWT or session authentication headers to verify the requesting user.
  3. Validate transaction hashes on-chain or via payment gateway APIs (e.g. Stripe / Solana RPC / Aztec RPC) to confirm funds were received.

Acceptance Criteria

  • Endpoint requires valid authorization headers or signed payload.
  • On-chain transaction signature or payment processor charge ID is verified server-side.
  • Unauthenticated or fake requests are rejected with 401/403 HTTP status.
  • Integration tests added for payment reconciliation security.

Files

  • app/api/payments/reconcile/route.ts

Notes

Currently, anyone can bypass payment and receive valid ticket IDs.

Guide contributeur