Skip to content

[Security] Payment amount validation missing server-side - client can manipulate payment values to underpay for AI services #240

Description

@anshul23102

Problem

In a micropayment architecture, the payment amount must be validated server-side against the service's defined price. If the server accepts whatever amount the client claims to have paid, a client can send a 0-value payment and still access the AI service:

// Vulnerable - trusts client-supplied amount:
func handlePayment(w http.ResponseWriter, r *http.Request) {
    var req PaymentRequest
    json.NewDecoder(r.Body).Decode(&req)
    // No check that req.Amount matches the service price
    if verifyTransaction(req.TxHash) {
        serveAIResponse(w, req.Prompt)  // served regardless of amount paid
    }
}

Proposed Fix

Look up the service price from a trusted source (config or database) and validate the on-chain amount matches:

type ServiceConfig struct {
    PriceUSDC  int64  // price in micro-USDC (6 decimals)
    ServiceID  string
}

func handlePayment(w http.ResponseWriter, r *http.Request, config ServiceConfig) {
    var req PaymentRequest
    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        http.Error(w, "Invalid request", http.StatusBadRequest)
        return
    }

    // Verify on-chain: get actual transferred amount from the blockchain
    actualAmount, err := getOnChainTransferAmount(req.TxHash, config.ServiceID)
    if err != nil {
        http.Error(w, "Payment verification failed", http.StatusPaymentRequired)
        return
    }

    // Validate amount meets minimum price:
    if actualAmount < config.PriceUSDC {
        http.Error(w, fmt.Sprintf("Insufficient payment. Required: %d, Received: %d",
            config.PriceUSDC, actualAmount), http.StatusPaymentRequired)
        return
    }

    serveAIResponse(w, req.Prompt)
}

Acceptance Criteria

  • Payment amount verified against on-chain data, not client-supplied value
  • Service price defined server-side in config, not derived from request
  • Underpayment returns 402 Payment Required with the expected amount
  • Amount tolerance (for gas fluctuations) configurable but defaults to 0
  • Test case verifies that a 0-value transaction is rejected

Metadata

Metadata

Assignees

Labels

triageNeeds maintainer triage.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions