CSRF Attack คืออะไร?
CSRF (Cross-Site Request Forgery) คือการโจมตีที่หลอกให้ Browser ของผู้ใช้ส่ง Request อันตรายไปยังเว็บไซต์ที่ผู้ใช้เข้าใจระบบอยู่แล้ว โดยแน่บว่าทำโดยไม่ได้ตั้งใจ เช่น หากผู้ใช้ Login อยู่บนธนาคารออนไลน์ แล้วคลิกลิงค์ภายนอก ลิงค์นั้นอาจเป็นการโอนเงินไปยังบัญชีของผู้โจมตีโดยอัตโนมัติ
ขั้นตอน CSRF Attack ทำงานอย่างไร?
- ผู้ใช้ Login เข้าสู่ภายงของ bank.com แล้ว Session Cookie ถูกบันทึกไว้ใน Browser
- ผู้อ่านเว็บอีแปบเช่น evil.com ที่มี Form/Link ที่ชีไป bank.com
- เมื่อ Browser ส่ง Request ไป bank.com จะแนบ Cookie ของ bank.com ไปด้วยตอนคันหา
- bank.com ตรวจสอบ Cookie แล้วดำเนินการตามคำสั่ง เพราะคิดว่าเป็นผู้ใช้จริง
ความแตกต่างภายภาค CSRF และ XSS
| คุณสมบัติ | CSRF | XSS |
|---|---|---|
| เป้าหมาย | Server-side Action | Client-side Browser |
| ต้องการ | เหยื่อเข้าสู่ภายมาแล้ว | ในเว็บมีช่องโหว๋ |
| วิธีโจมตี | Request Forgery | Script Injection |
| ผลลัพธ์ | การกระทำที่ไม่ได้ตั้งใจ | ขโมยข้อมูล |
วิธีป้องกัน CSRF Attack
1. ใช้ CSRF Token
CSRF Token เป็นค่า Random ที่เซิร์เวอร์สร้างและแนบไปกับ Form เมื่อ Server รับ Form Submit จะตรวจสอบว่า Token ถูกต้องหรือไม่ เนื่องจากเว็บปลอมไม่รู้ค่า Token นี้ จึงส่ง Token ที่ถูกต้องไปไม่ได้:
<!-- HTML Form พร้อม CSRF Token -->
<form method="POST" action="/transfer">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<input type="text" name="amount">
<button type="submit">โอนเงิน</button>
</form>
# ป้องกันใน Laravel
use Illuminate\Support\Facades\Route;
Route::post('/transfer', function() {
// Laravel ตรวจ CSRF Token อัตโนมัติ
});
2. ตั้งค่า SameSite Cookie Attribute
SameSite Attribute บอก Browser ว่าจะส่ง Cookie ในเงื่องหมองบ้าง:
# SameSite=Strict: ไม่ส่ง Cookie เบือกับ Cross-Site Request
Set-Cookie: session=abc123; SameSite=Strict; HttpOnly; Secure
# SameSite=Lax: ส่งเฉพาะเมื่อ Click Link (GET เท่านั้น)
Set-Cookie: session=abc123; SameSite=Lax; HttpOnly; Secure
# SameSite=None: ส่ง Cookie ทุกกรณี (ต้องใช้คู่กับ Secure)
Set-Cookie: session=abc123; SameSite=None; Secure
3. ตรวจสอบ Origin/Referer Header
เซิร์เวอร์ควรตรวจสอบว่า Request มาจาก Origin ที่เชื่อถือได้หรือไม่ หาก Referer หรือ Origin Header ไม่ตรงกันกับ Domain ของเว็บไซต์ ให้ปฏิเสธ Request นั้น
4. ใช้ Double Submit Cookie Pattern
ส่งค่า CSRF Token ทั้งใน Cookie และใน Request Body เพื่อให้ Server เปรียบเทียบว่าตรงกันหรือไม่ เหมาะสำหรับการเชื่อมต่องแบบ Stateless
5. ใช้ Custom Request Headers
เพิ่ม Header พิเศษ เช่น X-Requested-With: XMLHttpRequest ในคำขอ news API เนื่องจาก Browser จะไม่สามารถส่ง Custom Header พร้อม Cross-Site Request ได้เนื่องจากข้อจำกัด CORS
CSRF Token ใน Framework ยอดนิยม
| Framework | การป้องกัน CSRF |
|---|---|
| Laravel (PHP) | อัตโนมัติด้วย VerifyCsrfToken Middleware |
| Django (Python) | {% csrf_token %} ใน Template และ CsrfViewMiddleware |
| Spring (Java) | เปิดใช้งานในตัวแล้วใน Spring Security |
| Rails (Ruby) | protect_from_forgery พร้อมใช้แบบ Default |
| Express.js (Node) | ติดตั้ง csurf middleware |
สรุป
CSRF เป็นการโจมตีที่อาศัยกับความไว้เชื่อ Browser ที่ส่ง Cookie อัตโนมัติ การป้องกันที่ดีที่สุดคือการใช้ CSRF Token ร่วมกับ SameSite Cookie Attribute ที่เป็น Strict หรือ Lax Framework สมัยใหม่ส่วนใหม่หรือมีการป้องกันในตัวแล้ว แต่ควรเข้าใจหลักการให้เตังกตัดสินเชือมต่อง

