BuidlZone-Labs/zicket-web

Unauthenticated Payment Reconciliation API Endpoint Allows Arbitrary Ticket Generation

Aberta

#172 aberto em 29 de jul. de 2026

 (9 comentários) (0 reação) (1 responsável)TypeScript (43 forks)auto 404
Stellar Wavedifficulty: mediumhelp wantedsecurity

Métricas do repositório

Stars
 (4 estrelas)
Métricas de merge de PR
 (Métricas PR pendentes)

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.

Guia do colaborador