บทที่ 15 · Part 3 — API & Mobile Security

API Abuse & Transaction Integrity

Rate/cost limits, replay defense, request/webhook signing, idempotency, race/TOCTOU, double spend และ transaction-data binding

API อาจไม่มีช่องโหว่ทาง syntax และทุก request ผ่าน authentication แต่ผู้ใช้ที่มีสิทธิ์อาจเรียก promotion endpoint 10,000 ครั้ง, ส่ง withdrawal พร้อมกันหลาย connection หรือ replay callback ที่ลงนามถูกต้องจนระบบจ่ายเงินซ้ำ ช่องโหว่เหล่านี้อยู่ที่ business flow, freshness และ state invariant

Learning Outcomes

  • ออกแบบ rate/cost/concurrency limit หลายมิติได้
  • แยก request authentication, replay defense และ idempotency ได้
  • verify webhook/signature พร้อม timestamp/nonce/event state ได้
  • ผูก authorization proof กับ transaction detail/version ได้
  • ป้องกัน race, TOCTOU และ double spend ที่ storage/state boundary ได้
  • แยก Security enforcement จาก fraud/risk policy ที่ต้องมี human owner ได้

Abuse ไม่จำเป็นต้อง Exploit Code

ตัวอย่าง business-flow abuse:

  • signup หลาย account รับ incentive ซ้ำ
  • OTP/card testing สร้างต้นทุนและใช้ตรวจ credential
  • scrape exchange rate หรือ account existence
  • แบ่ง transfer/refund เพื่อหลบ threshold
  • reserve resource แล้วไม่ complete
  • ส่ง callback/request เดิมซ้ำ
  • เรียก operation พร้อมกันก่อน state update

API6:2023 เรียกความเสี่ยงนี้ว่า Unrestricted Access to Sensitive Business Flows

Rate Limit ต้องมีหลาย Dimension

Dimensionป้องกัน/จำกัด
Subject/accountabuse ต่อ identity
Credential/clientcompromised integration
IP/network/ASNtraffic source แต่ไม่ใช้เป็น identity
Device/installationdistributed account abuse บางรูปแบบ
Tenant/merchantnoisy neighbor และ contractual quota
Endpoint/operationexpensive/sensitive action
Business objectOTP recipient, card, beneficiary, promotion
Global/downstreamsystem/provider capacity และ cost

limit ควรรวม request rate, burst, concurrency, bytes, query cost และ monetary/vendor cost พร้อม response ที่ไม่ทำให้ client retry storm

Account Lockout ถูกใช้ทำ DoS ได้

attacker อาจจงใจชน limit ของ victim การเลือก block, delay, challenge, step-up หรือ review ต้องพิจารณาผลกระทบต่อผู้ใช้จริงและมี fraud/risk owner

Rate Limit ไม่หยุด Distributed Abuse ทั้งหมด

botnet กระจาย IP, account และ device ได้ ขณะที่ผู้ใช้จริงจำนวนมากอาจอยู่หลัง NAT เดียว จึงต้องรวม velocity/relationship/behavior, compromised credential, device signal, cost budget และ detection โดยมี privacy/retention policy

ระบบต้องตัดสินใจเมื่อ limiter unavailable ด้วย: fail open อาจเกิด loss; fail closed อาจหยุดบริการ degraded limit และระยะเวลาต้องออกแบบ/ทดสอบล่วงหน้า

แยก 3 Concept สำคัญ

Conceptคำถาม
Authentication/integrityrequest มาจาก identity/key ที่เชื่อถือและไม่ถูกแก้หรือไม่
Freshness/replay defenserequest นี้ใหม่และอยู่ใน acceptance window หรือไม่
Idempotencyการประมวลผล logical operation ซ้ำให้ผลเดียวเดิมหรือไม่

signature ที่ valid อาจถูก replay; nonce/timestamp ที่ใหม่ยังไม่ authorize resource; idempotency key ที่ไม่ authenticate caller อาจถูกเดาหรือชนกัน ทุกชั้นต้องผูก context เดียวกัน

Request Signing ต้องใช้ Protocol ที่ชัด

RFC 9421 HTTP Message Signatures กำหนด canonicalization และ covered components สำหรับ HTTP การออกแบบต้องระบุ:

  • algorithm/key ID และ key lifecycle
  • request components ที่ sign: method, target URI, authority, selected headers
  • content digest/body binding เมื่อ operation ต้องปกป้อง body
  • creation/expiry time และ nonce
  • audience/environment/partner context
  • server-side replay state/window
  • proxy transformations ที่ยอมรับ

ห้ามสร้าง concatenate(method + path + body) protocol เองโดยไม่มี canonicalization/versioning review และ signature ไม่แทน TLS หรือ resource authorization

DPoP ไม่ใช่ Transaction Signing

DPoP ผูก proof กับ key, method, URI และ access token hash ตาม protocol แต่ไม่ได้ sign amount, beneficiary หรือ request body/headers ส่วนใหญ่ High-value operation ต้องมี transaction-data binding หรือ message signature เพิ่มตาม profile

Webhook Verification

webhook เป็น Internet-facing state transition ไม่ใช่ “trusted callback”:

  1. จำกัด request bytes/content type ก่อนงานแพง
  2. อ่าน raw bytes ตาม provider signing specification
  3. เลือก key/algorithm จาก trusted configuration/key ID policy
  4. verify signature แบบ constant-time/library ที่เหมาะสม
  5. ตรวจ timestamp/expiry และ environment/destination
  6. ตรวจ event ID/replay uniqueness
  7. parse schema และ authorize provider/event type
  8. apply state transition แบบ idempotent/atomic
  9. เก็บ result แล้วตอบ retry-safe status

อย่า parse JSON แล้ว reserialize ก่อน verify ถ้า provider sign raw bytes และอย่า log signature/secret/payload ละเอียดโดยไม่มี data policy

Idempotency Key Design

Idempotency-Key เป็น API convention; ณ baseline นี้ยังไม่มี RFC final ที่กำหนด semantics สากล contract ต้องบอก scope, retention, conflict และ concurrent behavior เอง

bind key กับ:

principal/client + operation + resource/tenant + canonical request hash

state ที่ต้องเก็บ:

FieldPurpose
Scope + keyuniqueness boundary
Request hashreject key reuse กับ payload ต่าง
Statusprocessing / succeeded / failed-final
Outcome referenceส่ง response เดิมโดยไม่ทำ side effect ซ้ำ
Created/expiryretry contract และ storage lifecycle

Atomic Claim

INSERT INTO idempotency_records
    (principal_id, operation, idempotency_key, request_hash, status)
VALUES ($1, $2, $3, $4, 'PROCESSING')
ON CONFLICT DO NOTHING;

หลัง insert ต้องแยกกรณี:

  • record ใหม่ → process
  • key เดิม + hash เดิม + success → คืน outcome เดิม
  • key เดิม + hash ต่าง → conflict/reject
  • key เดิม + processing → wait/poll/conflict ตาม contract
  • stale processing → recover ด้วย state machine ไม่ทำ side effect แบบเดาสุ่ม

claim, state transition และ financial side effect ต้องออกแบบ atomic/transactional ให้เหมาะกับระบบ

Idempotency ไม่เท่ากับ Exactly Once

network อาจส่งซ้ำและ process อาจตายระหว่าง external side effect กับการบันทึกผล external provider ต้องรองรับ idempotency/reference/query status หรือมี reconciliation/compensation

Transaction Authorization: What Is Approved

proof/approval ต้องผูกกับรายละเอียดที่มีผล:

  • operation และ source account
  • amount/currency/fee/rate
  • beneficiary/destination
  • schedule/time window
  • transaction ID/version
  • policy/assurance context ตาม profile

ถ้าค่าใดเปลี่ยน approval เดิมต้อง invalid และก่อน execute ต้อง recheck current authorization/state เพื่อกัน TOCTOU

approved_transaction_hash = HASH(canonical_transaction_details)

canonical format/version ต้องกำหนดชัดและ hash ไม่แทน signature/authorization หาก attacker แก้ทั้ง data และ hash ได้

Race Condition และ TOCTOU

รูปแบบผิด:

1. SELECT balance = 100000
2. if balance >= 80000: allow
3. concurrent request ทำเหมือนกัน
4. ทั้ง 2 UPDATE balance - 80000

mutex ใน process เดียวไม่พอเมื่อมีหลาย instance ใช้ database transaction, conditional update, unique constraint, locking/serialization หรือ atomic state machine ตาม invariant

ตัวอย่าง conditional update:

UPDATE wallet_balances
SET available_satang = available_satang - $1,
    version = version + 1
WHERE wallet_id = $2
  AND available_satang >= $1
  AND version = $3;

success ต้องตรวจ affected rows และ ledger ที่เป็นเงินจริงควรใช้ double-entry/append-only invariant ไม่ใช้ balance column เดียวเป็นบัญชีสุดท้าย

Double Spend ต้องป้องกันที่ State Boundary

control หลายชั้น:

  • idempotency ต่อ logical request
  • unique provider/transaction reference
  • atomic reserve/post state transition
  • ledger constraints และ balance invariant
  • concurrency test หลาย instance
  • reconciliation กับ external system
  • anomaly detection และ bounded manual correction

API gateway rate limit ลด load แต่ไม่รักษา ledger invariant และ request signature ไม่หยุด valid request 2 รายการที่ใช้ balance เดียวกัน

Retry และ Exceptional Conditions

contract ต้องระบุว่า error ใด retry ได้, client ใช้ key เดิมหรือใหม่, response timeout หมายถึงอะไร และ query status ได้หรือไม่

FailureSafe Design Question
timeout ก่อน responseside effect เกิดแล้วหรือยัง และ lookup ด้วย reference ได้ไหม
worker ตายหลัง provider callresult ถูก recover/reconcile อย่างไร
duplicate callbackunique event/state transition อยู่ที่ใด
limiter/policy store ล่มdegraded behavior และ duration คืออะไร
partial dependency failuretransaction ค้าง state ใดและใคร resolve

Security กับ Fraud Decision

Threshold ที่กระทบเงินต้องมี Human Owner

Security engineering สร้าง identity, integrity, limits, telemetry, policy enforcement และ safe state แต่ threshold เช่นวงเงิน, velocity, account hold, device risk และ manual review มี customer/financial impact ต้องถูกกำหนดโดย Product, Fraud/Risk, Operations, Security และ Compliance ที่มีอำนาจ

code ต้อง version/audit policy และบอก evidence ไม่ hardcode ค่าจากตัวอย่างหรือให้ model ตัดสินโดยไม่มี human governance/appeal path

Testing Checklist

  • limits ครอบคลุม principal/IP/device/tenant/object/global/cost/concurrency
  • limiter failure มี degraded behavior ที่ทดสอบแล้ว
  • authentication, replay defense และ idempotency แยกหน้าที่ชัด
  • request signature ครอบ covered components/context และมี replay state
  • webhook verify raw/canonical input ตาม spec + event uniqueness
  • idempotency bind caller/operation/request hash และ atomic claim/outcome
  • approval bind amount/currency/beneficiary/version และ invalid เมื่อข้อมูลเปลี่ยน
  • race/double-spend tests รันพร้อมกันข้ามหลาย instance
  • storage enforce invariant ด้วย transaction/constraint/state machine
  • fraud/risk threshold มี human owner, version, audit และ exception

สรุป

Transaction integrity ต้องต่อหลาย control: authenticate request, bind context, ตรวจ freshness, ทำ idempotency และ enforce invariant ที่ state boundary Rate limit ลด abuse/cost แต่ไม่แทน authorization, replay defense หรือ atomic ledger design

Further Reading