Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Security]: Payment verification replay vulnerability allows reusing same Stellar transaction across multiple investments

Open
#613 3 comments 0 reactions 1 assignee View on GitHub

Maintainers usually reply within 1 day

@Danitello123 is already working on this.

Since Oct 17, 2026.

  • #644 by @Danitello123 — closed without merging
  • #697 by @Danitello123 — open

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
52/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
postgresql, typescript

Research direction

Start with src/services/stellar/verify-payment.service.ts, especially the listed validation and transaction lookup sections, then inspect src/models/Transaction.model.ts and src/models/Investment.model.ts and their database migrations. Trace how a verified operation is linked to an investment and how conflicts are returned. Done means the sender wallet is checked, a payment operation cannot confirm multiple investments, and reuse returns 409 Conflict.

Written by the indexing model from the issue text.

Description

bug domain: backend domain: security priority: p0 Stellar Wave
Summary

In src/services/stellar/verify-payment.service.ts, verifyPayment checks that an on-chain transaction exists in Horizon and matches amount and escrow destination. However, it does NOT enforce global uniqueness on (stellarTxHash, operationIndex) across all database investments, nor does it verify that the transaction's source account matches the investor's wallet.

Location
  • File: src/services/stellar/verify-payment.service.ts (Lines 151-200, Lines 284-323)
      const linkedTransactions = await unitOfWork.findTransactionsByInvestmentIdForUpdate(
        lockedInvestment.id
      );
      return (
        operation.assetCode === this.config.usdcAssetCode &&
        operation.assetIssuer === this.config.usdcAssetIssuer &&
        operation.destination === this.config.escrowPublicKey &&
        operation.amount !== null &&
        amountsWithinDelta(operation.amount, expectedAmount, this.config.allowedAmountDelta)
      );
Impact
  1. A user can make one 100 USDC payment on Stellar, and call verifyPayment for multiple separate 100 USDC investment commitments using the same transaction hash. All investments become CONFIRMED while the platform only received funds once (double-crediting exploit).
  2. Any observer watching the Stellar blockchain for payments to the escrow address can submit other parties' transaction hashes to confirm their own investments.
Expected Behavior
  1. (stellarTxHash, operationIndex) must have a unique constraint across transactions and investments so no payment can be credited more than once.
  2. The payment operation's source account / sender address must match lockedInvestment.investorWallet.
Recommended Fix
  1. Add a unique index on (stellar_tx_hash, stellar_operation_index) in the transactions/investments tables.
  2. Check operation.source_account === investment.investorWallet during payment validation.
Scope
  • src/services/stellar/verify-payment.service.ts (Lines 144-252, 284-323)
  • src/models/Transaction.model.ts, src/models/Investment.model.ts
Acceptance Criteria
  • verifyPayment validates that operation.source_account matches the investor's wallet address (lockedInvestment.investorWallet).
  • Database enforces a unique constraint on (stellar_tx_hash, stellar_operation_index) across transactions and investments.
  • Calling verifyPayment with a transaction hash/operation index that has already confirmed another investment returns 409 Conflict.
Dominant language
TypeScript
Stars
0
Forks
82
Avg merge
1d 21h
Merged PRs (30d)
76

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from StellarState/SS-backend

All issues in StellarState/SS-backend

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.