ป้ายกำกับ: https

RESTful: update dataRESTful: update data

การอนุญาตให้ User ส่งข้อมูลมาแก้ไข ( Update ) หรือสร้างใหม่ ( Create ) ในระบบ RESTful API เป็นจุดที่อันตรายที่สุดหากไม่มีการควบคุมที่ดีครับ เพราะ Hacker อาจส่ง Field ที่เราไม่ได้อนุญาต ( เช่น is_admin, wallet_balance ) เข้ามาใน Request Body เพื่อแอบแก้ไขข้อมูลสำคัญได้

นี่คือสิ่งที่ต้องระวังและจัดการเพื่อให้ API ของคุณปลอดภัยครับ


การควบคุมฟิลด์ที่อนุญาต ( Mass Assignment Protection )

นี่คือเรื่องที่สำคัญที่สุด หรือที่เรียกว่า “Allowlist” ( ไม่ใช่ Blocklist ) คือเราต้องระบุให้ชัดเจนว่า Column ไหนบ้างที่อนุญาตให้แก้ไขได้

  • Allowed Columns ( Fillable ): กำหนดใน Model หรือ Controller ว่า field ไหนที่รับค่าได้ เช่น first_name, last_name, phone
  • Guarded Columns: ห้ามรับค่าอย่างเด็ดขาด เช่น id, role, password_hash, created_at

การทำ Data Validation & Sanitization

อย่าเชื่อใจข้อมูลที่มาจาก Client แม้แต่ตัวอักษรเดีย

  • Type Checking: ถ้าช่องนี้เป็นตัวเลข ( Integer ) ต้องตรวจสอบว่าเป็นตัวเลขจริงไหม
  • Range & Length: เบอร์โทรศัพท์ต้องไม่เกิน 10 หลัก, อายุต้องอยู่ระหว่าง 0-120
  • Sanitization: ล้างอักขระพิเศษ (เช่น <script>) เพื่อป้องกัน XSS (Cross-Site Scripting) และตรวจสอบ Single Quote เพื่อป้องกัน SQL Injection

การตรวจสอบสิทธิ์ ( Authorization )

ไม่ใช่แค่ Login ผ่าน (Authentication) แล้วจะแก้ได้ทุกอย่าง ต้องเช็คด้วยว่า “เขามีสิทธิ์แก้ Record นี้ไหม”

  • Ownership Check: User A ต้องไม่สามารถใช้ PATCH /users/1 เพื่อไปแก้ข้อมูลของ User B ได้
  • Role-Based Access Control ( RBAC ): เฉพาะ Admin เท่านั้นที่เปลี่ยนสถานะ status: "verified" ของบทความได้

ความแตกต่างระหว่าง PUT และ PATCH

การใช้ Method ให้ถูกช่วยลดโอกาสข้อมูลพัง ( Data Integrity ) ได้

  • PUT: เป็นการ “แทนที่” ทั้งหมด หากส่งมาไม่ครบ Field ที่หายไปอาจกลายเป็น NULL ( อันตรายมาก )
  • PATCH: เป็นการ “แก้ไขบางส่วน” เฉพาะ Field ที่ส่งมา ซึ่งปลอดภัยและนิยมมากกว่าในการทำ Update

การใช้ DTO ( Data Transfer Object )

ในระบบขนาดใหญ่ เราจะไม่ส่ง Request Object ตรงๆ เข้าไปที่ฐานข้อมูล แต่จะใช้ DTO เป็นตัวคั่น

  1. รับ Request เข้ามา
  2. Map เฉพาะข้อมูลที่ต้องการใส่ใน DTO ( ขั้นตอนนี้จะคัดฟิลด์ที่ไม่เกี่ยวออกไปโดยอัตโนมัติ )
  3. ส่ง DTO ไปจัดการต่อใน Service/Database

🛠 ตัวอย่างการจัดการในทางปฏิบัติ ( Pseudo-code )

// ตัวอย่างแบบอันตราย (Don't do this)
// รับมาทุกอย่างแล้วบันทึกเลย -> Hacker สามารถส่ง { "role": "admin" } มาได้
User.update(req.body); 

// ตัวอย่างแบบปลอดภัย (Allowed Columns)
const allowedFields = ['first_name', 'last_name', 'bio'];
const updateData = {};

allowedFields.forEach(field => {
    if (req.body[field] !== undefined) {
        updateData[field] = req.body[field];
    }
});

// ตรวจสอบสิทธิ์ก่อนบันทึก
if (user.id === req.user.id || req.user.isAdmin) {
    User.update(updateData);
}

⚠️ ข้อควรระวังเพิ่มเติม ( Nginx & Security )

เมื่อคุณจัดการเรื่อง Security ในระดับ Code แล้ว อย่าลืมระดับ Infrastructure ด้วย

  • Rate Limiting: ป้องกันการยิงถล่มเพื่อเดาข้อมูล ( Brute Force ) โดยตั้งค่าใน Nginx
  • HTTPS Only: ข้อมูลที่ส่งผ่าน Method POST/PATCH ต้องถูกเข้ารหัสเสมอ เพื่อป้องกันการดักจับข้อมูลระหว่างทาง ( Man-in-the-Middle )

อ่านเพิ่มเติม