ทำความเข้าใจกับ CSRF (Cross Site Request Forgery) ตอนที่ 1

เมื่อวันก่อนมีโอกาสได้เห็นเมล์โต้ตอบระหว่างหัวหน้ากับทีมออฟชอร์ ทำให้ค้นพบว่า Web developer หลายๆคนที่อยู่ในระดับ Senior ยังมีความเข้าใจที่ผิดๆเกี่ยวกับการโจมตีรูปแบบนี้ ผมเลยคิดว่าน่าจะเป็นประโยชน์ในการอธิบายเรื่องนี้ในรูปแบบภาษาไทย

เนื้อหามีดังนี้

  1. CSRF คืออะไร?
  2. การป้องกัน CSRF แบบที่ไม่ได้ผล
  3. การป้องกัน CSRF ที่เป็นที่นิยม
  4. หัวข้อที่ควรรู้เมื่อพูดถึง CSRF
    1. CORS (Cross-Origin Resource Sharing)
    2. HttpOnly
    3. XSS

1. CSRF คืออะไร?

ลองนึกภาพว่าคุณกำลังเปิดแว็บของแบ็งค์อยู่ ระหว่างนั้นก็เปิดเว็บไซต์อื่นดูเล่นๆแล้วคลิ๊กไปโดนลิ้งก์นึง

http://yourbank.com/account/transfer?to=maliciousAccount&amount=20000

ถ้าเว็บของแบ็งค์ไม่มีการป้องกันที่ดี เงินก็จะถูกโอนไปให้คนอื่นโดยไม่รู้ตัว

แบ็งค์นี่ส่วนใหญ่จะไกลตัวไป เพราะส่วนใหญ่มี OTP (One-Time Password) ป้องกัน ลองดูกรณีที่เกิดขึ้นได้ทุกเว็บไซต์ เช่นการเปลี่ยนรหัสผ่าน

http://yourfavoritesite.com/changepassword.php?newPassword=igotyou

เช่นเดียวกัน ถ้าเว็บไซต์ไม่มีการป้องกันที่ดี ขอเพียงแค่ผู้ใช้เว็บไซต์ไปเปิดเว็บที่มีลิ้งก์แบบนี้อยู่ขณะที่กำลังเข้าเว็บไซต์ปกติอยู่ รหัสผ่านก็โดนเปลี่ยนไปเรียบร้อยโดยไม่ทันตั้งตัว

ถึงจุดนี้บางคนอาจจะสังเกตว่าถ้าไม่ไปกดลิ้งก์แปลกๆก็ไม่น่าจะมีปัญหาอะไร แต่จริงๆแค่คุณโหลด resource ก็อาจจะโดนไปแล้วก็ได้ ตัวอย่างเช่น


<img src="http://yourfavoritesite.com/changepassword.php?newPassword=igotyou" width="0" height="0" border="0">

อันนี้ยิ่งแย่ใหญ่ เพราะ browser จัดการโหลด URL ของ <img> ให้เสร็จสรรพโดยไม่รู้ตัว

2. การป้องกัน CSRF แบบที่ไม่ได้ผล

เว็บที่่ไม่ทำการป้องกัน CSRF เป็นอันตรายอยู่แล้ว แต่เว็บที่ทำการป้องกัน CSRF แบบผิดๆนี่ก็อันตรายไม่แพ้กันครับ ทีมโปรแกรมเมอร์จะคิดว่าตัวเองปลอดภัยแล้ว โดยไม่รู้เลยว่าหายนะรอเวลามาหาอยู่

ดังนั้น ก่อนที่จะไปดูว่าการป้องกัน CSRF ยังไง ลองมาดูกันก่อนนะครับว่าวิธีไหนที่ใช้ไม่ได้ผลบ้าง เวลาเจอคนที่เข้าใจผิด หรือไปรับโค้ดที่ใช้การป้องกันแบบนี้อยู่ จะได้รู้ตัวทัน

2.1 ใช้ POST

ตัวอย่างที่เห็นในตอนแรก เป็นแบบที่ส่ง parameter ด้วย GET ใน URL  บางคนเลยคิดว่า ถ้าใช้ POST แล้ว น่าจะปลอดภัย

ผิดถนัดเลยครับ ลองคิดดูว่าถ้าผู้ใช้เปิดเว็บที่มี HTML กับโค้ด JS นี้อยู่จะเป็นอย่างไร

<body onload="document.form[0].submit()">


<form action="http://yourfavoritesite.com/changePassword.php" pamethod="POST">
<input type="hidden" name="newPassword" value="igotyou"/>
<input type="submit" value="" />
</form>


</body>

สรุปได้ว่า แค่เปิดเว็บ POST request ก็โดนส่งโดยอัตโนมัติ  ไม่ได้ช่วยให้ปลอดภัยขึ้นเลย

2.2 ใช้ HTTPS หรือ Cookie ที่มี Secret code

วิธีพวกนี้ไว้สำหรับป้องกันการโจมตีแบบอื่น แต่ไม่ใช่กรณีของ CSRF ครับ

CSRF จะทำการ”สวมรอย”แล้วส่ง request จากเว็บบราวเซอร์ของผู้ใช้ ซึ่งทำให้มีทั้ง Cookie แล้วก็ได้ encryption ของ HTTPS ไปโดยอัตโนมัติ

ผู้โจมตีไม่มีความจำเป็นที่จะต้องรู้ค่าของ Cookie เลย เพราะลิ้งที่โหลดก็ผ่าน Browser ของผู้ใช้โดยตรงอยู่แล้ว

2.3 เว็บมีหลายขั้นตอนในการทำ Transaction

วิธีนี้ทำให้ CSRF ได้ยากขึ้น แต่ก็ป้องกันไม่ได้อยู่ดี ผู้โจมตีสามารถยิง Request ตามลำดับขั้นตอนด้วย JavaScript หรือลวงให้ผู้ใช้กดเข้าเว็บตามเสต็บแล้วซ่อน request ไว้ในเพจก็ได้

ตอนถัดไปเราจะมาดูหัวข้อ 3 กับ 4 กันครับ

ต่อ ตอนที่ 2

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: