ข้ามไปยังเนื้อหา

Rate Limiting & Validation

มีสองแนวป้องกันที่ทำให้ความปลอดภัยของ API สมบูรณ์ขึ้น: การจำกัดความถี่ที่ผู้เรียกใช้สามารถยิงเข้ามาหาคุณได้ และการไม่เชื่อสิ่งที่พวกเขาส่งมาเลย

Rate limiting จำกัดจำนวน request ต่อ client ในแต่ละช่วงเวลา (window) เพื่อกันทั้งการใช้งานในทางที่ผิด client ที่ทำงานเพี้ยน และลูปที่หลุดมาโดยไม่ตั้งใจ เมื่อผู้เรียกเกินโควตา ให้ตอบ 429 Too Many Requests พร้อม header Retry-After บอกว่าให้กลับมาลองใหม่เมื่อไหร่ และควรประกาศ budget ที่เหลือไว้ด้วย header RateLimit-Limit, RateLimit-Remaining และ RateLimit-Reset

algorithm ที่พบบ่อยคือ token bucket: แต่ละ client มีถังหนึ่งใบที่เติม token กลับเข้าไปด้วยอัตราคงที่ แต่ละ request ใช้ token ไปหนึ่งตัว ถังที่ว่างเปล่าหมายถึง 429

JavaScript

ทุกค่าที่มาจาก client เชื่อถือไม่ได้จนกว่าจะผ่านการ validate ความเสี่ยงหลัก ๆ ได้แก่:

  • Injection — อย่าสร้าง SQL/command ด้วยการต่อ string เด็ดขาด ให้ใช้ parameterized query
  • Mass assignment — อย่าเอา request body ไป spread ทับลงบน model แบบไม่ดูตาม้าตาเรือ ให้รับเฉพาะ field ที่อยู่ใน allowlist เท่านั้น มิฉะนั้น user อาจตั้งค่า isAdmin: true ได้
  • Oversized payloads — จำกัดขนาด request body และความยาวของ array เพื่อหลีกเลี่ยงการทำให้ resource หมดเกลี้ยง
  • Type and range — validate ชนิดข้อมูล, ความยาว และช่วงค่าด้วย schema และปฏิเสธด้วย 422 (ดู Validation Errors)
ข้อดี (Rate Limiting)ข้อแลกเปลี่ยน
ป้องกัน abuse และ DDoSlegitimate spike traffic อาจ fail
ป้องกัน credential stuffing และ brute forceต้องออกแบบ limit ที่เหมาะสม — ไม่เข้มเกินหรือหย่อนเกิน
ลด cost ของ downstream service เช่น LLM APIrate limit shared ใน distributed system ต้องใช้ Redis
บอก client ผ่าน header ว่าเหลือ quota เท่าไรuser experience แย่ถ้า error ไม่อธิบาย

Rate Limit โดยไม่บอก Client อาการ:

  • 429 Too Many Requests โดยไม่มี header บอกว่าเหลือ quota เท่าไรและ reset เมื่อไร
  • client ไม่รู้ว่าต้องรอนานแค่ไหน — retry loop ทำให้แย่ลง
  • ส่ง Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset เสมอ

Input Validation ที่ไม่ Sanitize อาการ:

  • รับ name: "<script>alert(1)</script>" แล้วเก็บและแสดงโดยไม่ sanitize
  • XSS เมื่อ API response ไปแสดงใน web app
  • validate type/format และ sanitize string input ก่อน store

💡 ตัวอย่างจากของจริง

GitHub API:

  • rate limit: 5000 requests/hour สำหรับ authenticated request
  • header: X-RateLimit-Limit: 5000, X-RateLimit-Remaining: 4999, X-RateLimit-Reset: 1609459200

Stripe API:

  • rate limit ตาม endpoint: /charges มี limit ต่างจาก /events
  • 429 พร้อม Retry-After header — client รู้ว่าต้องรอกี่วินาที
status และ header ใดที่บ่งบอกว่า client ถูก rate limit?
mass assignment คืออะไร และป้องกันอย่างไร?
ควรป้องกัน SQL injection อย่างไร?