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

ใครที่ยังไม่ได้อ่านตอนก่อนๆ ไปดูได้ที่นี่นะครับ  (ตอนที่ 1) (ตอนที่ 2)

มาถึงตอนสุดท้ายแล้วครับ รอบนี้เราจะลงลึกไปในหัวข้ออื่นๆที่เกี่ยวข้องเพื่อให้เข้าใจวิธีการป้องกัน CSRF กันมากขึ้น

4. หัวข้อที่ควรรู้เมื่อพูดถึง CSRF

4.1 Same Origin Policy กับ CORS (Cross-Origin Resource Sharing)

ตอนที่แล้ว ได้เล่าให้ฟังว่ามีวิธีการอื่นๆนอกเหนือจากการใช้ Token เพื่อป้องกัน CSRF หนึ่งในนั้นก็คือการใช้ Origin Header

แนวคิดคือใส่ Header เพิ่มเข้าไปใน Request ตัวนึงโดยตั้งชื่อว่า Origin  แล้วก็ให้เซอร์เวอร์เช็คดูว่าใช่ของเว็บตัวเองรึเปล่า ถ้าหาก Origin ไม่ถูก (Host name, Protocol, หรือ Port ไม่ตรง) ก็เดาได้เลยว่า Request ที่ได้มานี่ไม่ใช่ของแท้แน่ๆ

การจะทำให้ Origin Header ปลอดภัย ก็ทำโดยการไม่ยอมให้ใครเลยนอกจากตัว Browser เองแก้ไขค่าตัวนี้ได้ ซึ่งในบราวเซอร์ใหม่ๆก็รองรับวิธีนี้แล้ว แต่ถ้าเจอบราวเซอร์เก่าๆขึ้นมา ไม่มี Origin Header เซอร์เวอร์ก็เดาไม่ถูกเหมือนกันว่า Request นี่โดนปลอมแปลงมารึเปล่า

บางคนก็คิดว่า อย่างนี้ปลอมทั้ง Request ผ่านทางอื่นนอกบราวเซอร์ได้สิ แต่ในกรณีนั้น ผู้โจมตีจะต้องได้สิทธิ์เข้าไปเยอะมากถึงขนาดรันโค้ดที่ใช้ปลอม Request ทั้งดุ้นได้  ณ ถึงจุดนั้นผู้โจมตีคงไม่ต้องสนใจำ CSRF แล้วล่ะครับ มีอย่างอื่นให้ทำอีกเยอะ (และอย่าลืมว่าทุกอย่างโดนเข้ารหัสด้วย HTTPS  จะ Man in the middle มาแก้ Header ก็ไม่ได้)

ที่กล่าวมาคือ Same Origin Policy ครับ อีกกรณีหนึ่งคือต้องการส่งข้าม Origin ก็จะเป็น CORS ซึ่งจะมี Header กับวิธีการยุ่บยั่บที่เอาไปเขียนบล็อคเพิ่มยาวๆได้อีกโพสต์นึงเลย ใครที่เคยส่ง Request ข้าม origin ก็จะคงจะเคยเจอปัญหามาแล้ว ใครสนใจอยากอ่านต่อ แนะนำลิ้งก์นี้ครับ http://www.html5rocks.com/en/tutorials/cors/

4.2 XSS (Cross-Site Scripting)

ผมเดาว่าหลายๆคนที่สนใจอ่านกันมามาถึงตอนสามนี้น่าจะเคยได้ยินเจ้า XSS ดีอยู่แล้ว เพราะโดนทีเจ็บหนัก เป็นข่าวดัง ผมจะเล่าแค่คร่าวๆละกันนะครับ

ลองนึกภาพว่าคุณทำ Forum ให้ผู้ใช้โพสต์ HTML Tag ได้  แต่วันดีคืนดี ผู้ใช้คนหนึ่งแทนที่จะใส่แค่ HTML tag  ดันแทรก <script> ชี้ไปยังอีกเว็บไซต์หนึ่งขึ้นมา เนื่องจาก Script นั้นถูกรันอยู่ในเพจเดียวกับ Forum ของคุณ มันจึงสามารถสวมรอยปลอม Request ของคนที่เข้ามาดู Forum หน้านั้นๆได้

อันนี้เกี่ยวกับ CSRF ยังไง คือไม่เกี่ยวโดยตรงครับ แค่อยากจะบอกว่าเว็บคุณโดนเจาะด้วย XSS ได้ ต่อให้ส่ง Token ไปก็ไม่มีประโยชน์ครับ เพราะผู้จู่โจมสามารถแทรกสคริปต์เพื่ออ่าน Cookie แล้วก็หยิบไปใช้สร้าง Request ได้สบายใจเฉิบ  ในบางกรณีก็ส่งสคริปต์เข้าไปสร้าง Error หรือสร้างช่องโหว่ให้เจาะเข้าสู่ส่วนสำคัญอื่นๆได้  การโดน XSS เจาะนี่รุนแรงจนไม่ต้องห่วงเรื่อง CSRF เลย

วิธีป้องกัน XSS นี้เหมือนจะง่ายครับ คือจัดการฆ่าเชื้อ (Sanitize) หรือตรวจ Input ของ User ที่เข้ามาให้ละเอียด  แต่การวิธีการฆ่าเชื้อนี่ก็ซับซ้อนกว่าที่คิดนะครับ ปกติก็แนะนำว่าให้ใช้ Open Source Library ที่ตรวจผ่านกันมาหลายตา ใครอยากอ่านละเอียดต่อ แนะนำลิ้งก์นี้ครับ http://resources.infosecinstitute.com/how-to-prevent-cross-site-scripting-attacks/

ในโลกแห่งความเป็นจริงดูจะทำยากกว่าที่คิดครับ  Paypal พึ่งโดนเจาะด้วยวิธีนี้ไป (ซึ่งซับซ้อนหลายตลบนิดนึง ลองอ่านข่าวนี้ดู http://www.v3.co.uk/v3-uk/news/2424706/paypal-xss-vulnerability-exposed-by-bitdefender ) ไม่แน่ใจเหมือนกันว่าเป็นเพราะลืม Sanitize หรือ Sanitizer ตรวจพลาดในกรณีนี้ เพราะเห็นว่าอัพ input เป็น XML ไฟล์

4.3 HttpOnly

ถ้าฟังคนเถึยงกันเรื่อง CSRF อาจจะคุยไปถึง XSS และมีการยกหัวข้อ HttpOnly ขึ้นมา

HttpOnly เป็น Flag ใน Request Header ตัวหนึ่งที่ชื่อว่า Set-Cookie ครับ ไอเดียก็คือ ถ้าเจ้าตัวนี้ถูกเซ็ตค่า JavaScript จะไม่สามารถเข้าถึงค่าใน Cookie ได้ ซึ่งทำให้เราไม่สามารถ ส่ง Token ผ่านทาง Cookie ได้

ดังนั้น โปรแกรมเมอร์บางคนก็เลยไม่ชอบวิธีการส่ง Token ผ่านทาง Cookie ในหัวข้อ 3.2 กับ 3.3 (ในตอนที่ 2) เพราะ JavaScript จะต้องอ่านค่านี้ ทำให้เซ็ต HttpOnly ไม่ได้

แล้วเจ้า HttpOnly มีไว้เพื่ออะไร คำตอบคือ เอาไว้บรรเทาผล (Mitigate) กรณีการโจมตีแบบ XSS ที่ทำสำเร็จครับ  สังเกตนะครับ ว่าเอาไว้บรรเทา ไม่ได้เอาไว้กัน แปลว่าโดนเข้าไปแล้ว แต่อยากให้ความรุนแรงของการโดนโจมตีสำเร็จลดน้อยลง

บรรเทายังไง คือ XSS ส่วนใหญ่เนี่ย ทำเพื่อขโมยข้อมูลใน Cookie ครับ พอได้ Cookie เสร็จก็เอาไปสวมรอย Session ได้สบายใจเฉิบ (เช่นในกรณีของ CSRF ถ้าสคริปต์ฝังตัวอยู่ในหน้าเดียวกันก็จะอ่าน Cookie เพื่อขโมย Token ได้)  ถ้าสนใจทดลอง เปิดเว็บไซต์แล้วหยิบค่าใน Cookie ไปเซ็ตใส่ในอีกบราวเซอร์ดู

ใครอยากอ่านต่อตัวอย่างของ XSS กับ HttpOnly ผมแนะนำลิ้งก์นี้ครับ > http://blog.codinghorror.com/protecting-your-cookies-httponly/

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

———————–

จบแล้วครับสำหรับตอนสุดท้าย ไม่น่าเชื่อเหมือนกันว่าแค่แรงบันดาลใจจากอีเมล์ที่เจ้านายเถียงกันออฟชอร์ จะทำให้เขียนบล็อคยาวได้ขนาดนี้

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

  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: