Currency conversions server-side, locked at transaction time
Why it matters
A client-side exchange rate is fetched at page load and may be stale seconds later. More critically, it can be tampered: any user with browser devtools can edit the rate in memory before submitting, receiving a conversion at an artificially favorable rate. OWASP A03 (Injection) and CWE-602 (Client-Side Enforcement of Server-Side Security) both flag trusting client-calculated financial values. PCI DSS Req-6.2.4 requires server-side validation of all input data used in financial operations.
Severity rationale
High because a client-side exchange rate is directly tamper-able via devtools, enabling users to execute currency conversions at fraudulent rates.
Remediation
Move all currency conversion logic into the server route and persist the locked rate with the transaction record. Never accept a converted amount or exchange rate from the client request body.
// src/app/api/transfers/route.ts
export async function POST(req: Request) {
const { fromAmountCents, fromCurrency, toCurrency } = await req.json();
// Fetch and lock the rate server-side
const rate = await getExchangeRate(fromCurrency, toCurrency);
const toAmountCents = Math.round(fromAmountCents * rate);
await db.transaction.create({
data: { fromAmountCents, toAmountCents, exchangeRate: rate, lockedAt: new Date() },
});
}
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Financial Form Validation Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-20 — Improper Input Validation
- owasp:2021 · A03
- cwe · CWE-602 — Client-Side Enforcement of Server-Side Security
- pci-dss:4.0 · Req 6.2.4 — Prevent common software attacks including injection and improper input validation
Taxons
History
- 2026-04-18·v1.0.0·Initial import from finserv-form-validation·automated