CSRF: Cross-Site Request Forgery คืออะไร
Cross-Site Request Forgery (CSRF) เป็นการโจมตีที่บังคับให้ผู้ใช้ปลายทางยืนยันความถูกต้อง (authenticated) บน web application โดย Attacker จะทำให้ผู้ใช้ที่เป็นเหยื่อทำการโดยไม่ตั้งใจ ตัวอย่างเช่น อาจเป็นการเปลี่ยนที่อยู่อีเมลในบัญชี เปลี่ยนรหัสผ่าน หรือ ทำการโอนเงิน มันก็คือการที่ Attacker หรือ Hacker ปลอมแปลง บน web application นั้นแหละ และยังไม่พอนะ Attacker สามารถควบคุมบัญชีผู้ใช้ได้อย่างสมบูรณ์ แต่ขึ้นอยู่กับว่าถ้าผู้ใช้ที่ถูกบุกรุกมีบทบาทพิเศษภายใน application เช่น เป็น Admin ของ application นั้นๆ Attacker สามารถควบคุมข้อมูลและ fucntion ทั้งหมดของ application ได้อย่างเต็มที่เลย
การทำงานของ CSRF
CSRF เป็นช่องโหว่ที่ Attakcer ส่ง HTML หรือ JavaScript ให้ Web browser ของเหยื่อส่ง HTTP request เพื่อไปกระทำการบางอย่างที่เป็นอันตรายต่อผู้ใช้งาน หลักการของ CSRF เป็นตัวอย่างดังรูป
- Attacker เตรียม request หรือ ปลอมแปลง web applicationนั้นๆ
- Attacker ส่ง html / javascript ให้ web browser หลังจากนั้น user Login เข้า web browser นั้น ด้วย Account ของ User เอง
- เมื่อ login เสร็จ และ Attacker จะได้ค่า session มาเก็บใน cookie บน web browser แล้ว user เข้าเว็บไซต์ของ Attacker โดยไม่ได้ตั้งใจ จากนั้น Website ของ Attacker บังคับให้ Browser ของ user ส่ง HTTP request ไปที่ web browser มันจะส่งค่า session ที่อยู่ใน Cookie ไปด้วย
- เมื่อ Server ได้รับ HTTP request จากข้อ 3 แล้ว check ค่า session ที่อยู่ใน cookie ถ้า Attacker ทำสำเร็จ ค่า session ถูกต้อง Attacker สามารถนำไปใช้งานต่อได้ จึงอนุญาตให้ process HTTP request นั้นต่อ ค่ะ
วิธีสร้างการโจมตี CSRF
สร้างโดยใช้ CSRF PoC ที่สร้างขึ้นใน Burp Suite Professional เพราะเป็นวิธีที่ไม่ยุ่งยากเท่ากับการที่สร้างการโจมตีโดยเรียก request ที่มี parameter จำนวนมาก
ดังนั้นเรามาดูวิธีใช้แบบ Burp Suite Professional กันเถอะ
- เลือก request ใน Burp Suite Professional ที่ต้องการทดสอบหรือหาประโยชน์
- จาก context menu ให้ คลิกขวา เลือกselect Engagement tools / สร้าง CSRF PoC
- Burp Suite จะสร้าง HTML ที่จะเรียกใช้ request ที่เราเลือก (ลบ cookies ซึ่งจะถูกเพิ่มโดยอัตโนมัติโดย browser ของเหยื่อ)
- แล้วเราจะสามารถปรับแต่ง option ต่างๆ ในตัวสร้าง CSRF PoC เพื่อปรับแต่งแง่มุมของการโจมตีได้ เราอาจจำเป็นต้องทำแบบนี้ในสถานการณ์ที่ไม่ปกติ บางอย่างเพื่อจัดการกับคุณลักษณะของ request ที่เป็นแบบ features
- คัดลอก HTML ที่สร้างขึ้นลงในหน้าเว็บ ดูใน browser ที่ลงชื่อเข้าใช้เว็บไซต์ที่มีช่องโหว่ และทดสอบว่า request ที่ได้ทำไว้ได้รับการออกเรียบร้อยแล้วได้รับการ execute แล้ว
ตัวอย่างการทำ CSRF
ก่อนดำเนินการโจมตี Attacker มักจะศึกษา application เพื่อให้ request ที่ปลอมแปลงดูเหมือนถูกกฎหมายมากที่สุด
ตัวอย่างเช่น Request GET สำหรับการโอนเงินผ่านธนาคาร $100 อาจมีลักษณะดังนี้:
GET http://netbank.com/transfer.do?acct=PersonB&amount=$100 HTTP/1.1
Attacker สามารถแก้ไข script นี้ จะทำให้มีการโอนเงิน $100 ไปยังบัญชีของตนเอง ตอนนี้ request ที่เป็นอันตรายอาจมีลักษณะดังนี้:
GET http://netbank.com/transfer.do?acct=AttackerA&amount=$100 HTTP/1.1
Attacker สามารถฝัง request ลงใน hyperlink ที่ดูน่าเชื่อถือแบบนี้:
<a href="http://netbank.com/transfer.do?acct=AttackerA&amount=$100">Read more!</a>
ซึ่งขั้นตอนนี้ Attacker สามารถแจกจ่าย hyperlink ผ่านอีเมลไปยังธนาคารของ user จำนวนมาก user ที่คลิก link ขณะ login เข้าบัญชีธนาคาร จะโอนเงิน $100 โดยไม่ได้ตั้งใจ
แต่ถ้าเว็บไซต์ของธนาคารใช้ request เฉพาะ POST จะไม่สามารถกำหนด frame request ที่เป็นอันตรายโดยใช้แท็ก <a> href ได้
อย่างไรก็ตาม การโจมตีสามารถส่งได้ในแท็ก <form> พร้อมกับการ execute แบบอัตโนมัติของ JavaScript แบบ embeddedt หรือแบบฝังได้
แบบฟอร์มดังกล่าวอาจมีลักษณะดังนี้:
<body onload="document.forms[0].submit()">
<form action="http://netbank.com/transfer.do" method="POST">
<input type="hidden" name="acct" value="AttackerA"/>
<input type="hidden" name="amount" value="$100"/>
<input type="submit" value="View my pictures!"/>
</form>
</body>
แนวทางการในการป้องกัน CSRF
Attacker สามารถเปิดการโจมตี CSRF ได้เมื่อ Attacker รู้ว่ามีการใช้ parameter และ value หลายๆค่าเข้าด้วยกัน ดังนั้นถ้า Attackerไม่รู้ค่า parameter หรือ ค่า value แล้วใช้การ validated จาก server เราจะสามารถป้องกันการโจมตี CSRF ได้
นี้วิธีการบางอย่างเท่านั้นที่ เราสามารถใช้เพื่อบล็อกการโจมตี Cross-Site Request Forgery !
1.Implement Anti-CSRF Token
Anti-CSRF token เป็นประเภทของการป้องกัน CSRF ฝั่ง server เป็น random string ที่รู้จักใน browser ของผู้ใช้และ web application เท่านั้น Anti-CSRF Token มักจะถูกเก็บไว้ในตัวแปร session บนเพจ โดยทั่วไปจะอยู่ใน field ที่ซ่อนอยู่ซึ่งถูกส่งไปพร้อมกับ request
ถ้าค่าของตัวแปร session และ hidden form field match ตรงกัน web application จะยอมรับ request ถ้าไม่ตรงกัน request จะถูกยกเลิก ในเคสนี้ Attacker ไม่รู้ค่าที่แน่นอนของ hidden form field ซึ่งจำเป็นสำหรับ request ที่จะได้รับการยอมรับ ดังนั้น Attacker จึงไม่สามารถเปิดการโจมตี CSRF ได้ อันที่จริง เป็นเพราะนโยบายที่มาเดียวกัน Attackerไม่สามารถอ่านคำตอบที่มีtokenได้
สมมติว่าเราใช้งาน web application ของโซเชียลมีเดีย บน www.example.com ในการเผยแพร่ข้อความในโปรไฟล์ ผู้ใช้กรอกแบบฟอร์ม HTML แล้วคลิกปุ่มส่ง
ซึ่งทำให้ web browser ส่ง request POST:
ถ้าผู้ใช้เข้าสู่ระบบและถ้า Attacker รู้ syntax ของ request นี้ Attacker สามารถใช้การโจมตี CSRF เพื่อเผยแพร่โฆษณาในโปรไฟล์ของผู้ใช้:
ด้วยเหตุผลนี้ web browser จึงส่ง request POST ต่อไปนี้:
ถ้า website ใช้ token เพื่อ ต่อต้าน CSRF แบบง่าย web server จะตั้งค่า token นั้นใน cookie session ของ web browser ของเราทันทีหลังจากที่เราเข้าสู่ระบบ การส่งแบบฟอร์มทั้งหมดจะมี hidden form field ซึ่งมี token วิธีนี้ช่วยขจัดช่องโหว่ของ CSRF ได้อย่างสมบูรณ์เลยค่ะ
จากนั้น server จะตรวจสอบว่าทุก request POST มีลักษณะดังนี้:
ถ้า Attacker พยายามทำการปลอมแปลง request หรือ CRSF โดยใช้ website ที่เป็นอันตราย พวกเขาจะไม่รู้ token ตอนนี้ที่ตั้งค่าไว้ใน cookie server ของเรา จะไม่ดำเนินการตาม requestถ้าไม่มี token นี้ การโจมตีจึงไม่สำเร็จ
2.ใช้ SameSite Flag ใน Cookies
SameSite flag in cookiesเป็นวิธีการใหม่ในการป้องกันการโจมตี CSRF และปรับปรุงความปลอดภัยของ Web applicaiton ในสถานการณ์ข้างต้นที่ได้บอกไว้ เราเห็นว่า https://attacker.com/ สามารถส่ง request POST ไปยัง https://example.com/ พร้อมกับ cookie ของ session นี้ไม่ซ้ำกันสำหรับผู้ใช้ทุกคน ดังนั้น web applicaiton จึงใช้ cookie นี้เพื่อแยกแยะผู้ใช้และตรวจสอบว่าพวกเขาลงชื่อเข้าใช้หรือไม่
ถ้า cookie session ถูกทำเครื่องหมายเป็น cookie SameSite cookie นั้นจะถูกส่งไปพร้อมกับ request ที่มาจาก domain เดียวกันเท่านั้น ดังนั้น เมื่อ https://example.com/index.php ต้องการส่ง request POST ไปยัง https://example.com/post_comment.php จะได้รับอนุญาต อย่างไรก็ตาม https://attacker.com/ ไม่สามารถส่ง request POST ไปที่ https://example.com/post_comment.php เนื่องจาก cookie ของ session มีต้นกำเนิดมาจาก domain อื่น จึงไม่ส่งไปพร้อมกับ request
Reference: