ป้องกันไม่ให้เว็บไซต์โดน Hack ด้วย CSRF
หากคุณเป็น Developer ที่กำลังสร้าง Application หรือ สร้างสำเร็จไปแล้ว คุณเคยสังเกตกันบ้างไหมครับ ว่า Project ที่เราสร้างไปนั้นมีความปลอดภัยมากน้อยแค่ไหน...? วันนี้ผมอยากจะมาแนะนำให้ทุกคนรู้จักการเพิ่มความปลอดภัยขั้นพื้นฐานที่เป็นมาตรฐานที่ทุก Application ควรจะมีเพื่อป้องกัน นั่นคือ CSRF และ XSS
CSRF และ XSS ประกอบด้วย
-
ทำไม Application ถึงต้องมีความปลอดภัย?
-
XSS ตัวร้าย คืออะไร และมีวิธีป้องกันอย่างไรบ้าง?
-
CSRF ตัวร้าย คืออะไร และมีวิธีป้องกันอย่างไรบ้าง?
ทำไม Application จึงต้องมีความปลอดภัย?
อยากให้ลองคิดง่าย ๆ เลยนะครับ หากเว็บไซต์ Google, Facebook, Instagram หรือ Twitter ที่เราใช้งานกันทุกวันไม่มีความปลอดภัยเราจะยังใช้กันอยู่ไหม? ตอบได้เต็มปากเต็มคำเลยว่า ไม่! ใช่ไหมครับ?
เพราะการที่ Application ไหนที่ไม่มีความปลอดภัย ผู้ใช้งานจะไม่มีความเชื่อมั่นในการใช้งานและมีโอกาสที่ Application นั้น จะสร้างปัญหาตามมาได้อีกมากมายจาก ผู้ไม่หวังดี หรือ "Hacker" นั่นเอง แน่นอนว่าคงไม่มีผู้ใช้งานคนไหนที่อยากให้ข้อมูลของตัวเอง หรือ Session ของตัวเองถูกขโมยไปใช้งานในทางที่ไม่ดี
ถ้าให้ยกตัวอย่างแบบร้ายแรงเลยคือ E-Banking / Internet Banking / Mobile Banking หรือ เว็บธนาคารที่ให้บริการออนไลน์ ถ้าหากเราเป็นผู้ใช้งานของเว็บนั้น แน่นอนว่าหนึ่งในบริการที่เราใช้ประจำนั่นก็คือ การโอนเงิน ไปสู่บัญชีต่าง ๆ แต่ถ้าหากว่า Application มีความปลอดภัยต่ำ จะทำให้ผู้ไม่หวังดีหาโอกาสดี ๆ ขโมย Session ของเราไปใช้ และเมื่อผู้ไม่หวังดีหรือ "Hacker" ทำการวางสคริปต์ และทำการขโมยมาได้โดยวิธีการใดวิธีการหนึ่ง เขาก็จะสามารถเข้าสู่ระบบโดยเสมือนว่าเราเป็นคนล็อกอินเอง หลังจากนั้นผู้ไม่หวังดีจะทำธุรกรรมใด ๆ ได้อย่างที่ต้องการโดยที่เจ้าของบัญชีอาจจะไม่รู้เรื่องเลย
เอาล่ะ... ในเมื่อมันมีความเสี่ยงมากมายขนาดนี้เราไปรู้จักการขโมย Session ในแต่ละรูปแบบ และวิธีการป้องกันกันเถอะ
XSS ตัวร้าย คืออะไร และมีวิธีป้องกันอย่างไรบ้าง?
XSS หรือชื่อเต็มคือ Cross Site Scripting เป็นอีกหนึ่งการขโมยข้อมูลที่เป็นพื้นฐานและควรป้องกันอย่างมากเพราะสามารถขโมยได้ง่าย ๆ ก่อนอื่นเราต้องมารู้จักเจ้าวิธีการนี้ซะก่อน
หากเราสร้าง application ตัวหนึ่งมา ซึ่งใช้สำหรับขายของมือสองโดยผู้ใช้งานที่เข้ามานั้นจะมีจุดประสงค์อยู่สองอย่างนั่นก็คือ เข้ามาเพื่อลงทะเบียน หลังจากนั้นจะลงสิ่งของที่ตัวเองต้องการจะขายตั้งราคา ตั้งคำอธิบายและอื่น ๆ หลังจากนั้นสินค้าชิ้นนี้จะไปอยู่หน้า รวมสินค้ามือสองที่จะมีสินค้าของผู้อื่นอยู่ในรายการด้วย ผู้ใช้จุดประสงค์ที่สอง คือผู้ใช้ที่เข้ามาเพื่อจะดูสินค้ามือสองที่ผู้ใช้คนอื่นลงทะเบียนและลงสินค้ามือสองไว้ โดยจะต้องลงทะเบียนพร้อมกับผูกบัตรเครดิตหรือเดบิต เพื่อง่ายและรวดเร็วต่อการซื้อสินค้า หลังจากนั้นจะสามารถเข้าไปดูรายการสินค้ามือสองได้ ก็ดูไม่มีพิษ ไม่มีภัย อะไรเลย…
แต่แอปพลิเคชันนี้ไม่ได้มีการป้องกัน XSS ไว้ ทำให้ผู้ไม่หวังดีเข้ามาสมัครเป็นผู้ขายสินค้า และในขณะที่กำลังกรอกข้อมูลอยู่นั่นเขาก็ได้แอบใส่ script ไว้ ( เป็นสคริปต์ที่เมื่อถูก run จะให้ส่ง cookie ของคนที่กดไปสู่ server ของผู้ไม่หวังด) ในช่องที่เป็นคำอธิบาย ซึ่งข้อมูลตรงนี้จะโชว์ทุกครั้งเมื่อมีคนมากดดูรายละเอียดสินค้าชิ้นนั้นและทำการกดบันทึก เมื่อมีผู้ใช้งานที่ต้องการจะซื้อสินค้ามือสองและกดเข้าไปดูรายการสินค้าชิ้นนั้น จะทำให้เว็บเบราว์เซอร์ run script นั้นทันที ทำให้ผู้ไม่หวังดีได้ session ของคนนี้ไป และเขาสามารถเข้าสู่ระบบด้วย session น้ัน และกดซื้อของหรืออะไรได้ทุกอย่างเพราะผู้ใช้ได้ผูกบัตรเอาไว้
วิธีป้องกัน XSS ตัวร้าย
ในสมัยก่อนนั้นเจ้าตัว XSS นี้ถือเป็นสิ่งที่น่ากลัวและควรกังวลเป็นอย่างมาก แต่ข่าวดี! Modern web browser สมัยนี้นั้นมีการดักป้องกันไว้ไม่ให้ run inline script ทำให้เมื่อเบราว์เซอร์ตรวจจับได้ว่าหน้าเว็บที่โหลดมานี้มีการแอบฝัง script ไว้เบราว์เซอร์จะบล็อคและไม่ให้รัน script นั้น เจ๋งไม่ใช่น้อย แต่ถ้าหากใครยังกังวลว่าแล้วเบราว์เซอร์เก่า ๆ จะปลอดภัยไหมก็มีวิธีป้องกันเพิ่มเช่นกันโดย
- การใส่ header เพิ่มเพื่อให้เว็บเบราว์เซอร์ทำการป้องกัน รายละเอียดตามลิ้งค์นี้เลยครับ
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection - กรองข้อมูลที่ user กรอกเข้ามาว่ามี script อยู่หรือไม่ ถ้าหากมีจะต้องไม่ให้บันทึกลงฐานข้อมูล และ ปฎิเสธ request นี้
CSRF ตัวร้ายคืออะไร และมีวิธีป้องกันอย่างไรบ้าง?
CSRF หรือชื่อเต็มคือ Cross-site request forgery จะไม่เหมือนกับ XSS ที่จะต้องขโมย session โดยการที่ผู้ไม่หวังดีต้องได้ cookie หรือ session ก่อน ถึงจะทำการเข้าไปกระทำสิ่งไม่ดี แต่วิธีการนี้เขาจะทำให้ผู้ใช้งานทั่วไปเป็นคนขโมยให้เขาเอง! โดยที่เขาแค่โกหกบางอย่างให้กับผู้ใช้เพื่อให้ผู้ใช้งานเผลอร้องขอ และผู้ไม่หวังดีจะได้ผลประโยชน์จากการที่ผู้ใช้งานร้องขอไป เพื่อไม่ให้งงไปกว่านี้ เราไปดูตัวอย่างที่เข้าใจง่ายๆกันเลยดีกว่า
หากผู้ใช้งานเข้าใช้งาน E- banking ตามปกติโดยเข้าไปโอนเงินให้คนอื่นๆเป็นประจำเรื่อยๆ โดยในการโอนเงินแต่ละครั้ง แน่นอนว่าปผู้ใช้งานจะต้องมีการร้องขอ (request) ไปหา server เพื่อทำการโอนเงินหรือร้องขอสิทธิอื่นๆ ซึ่งทุกครั้งที่ร้องขอนั้น ผู้ใช้งานจะต้องมี session หรือ cookie เพื่อส่งไปยืนยันว่าคนที่ส่งมานั้นมีสิทธิที่จะกระทำอะไรซักอย่างอาทิเช่น ผู้ใช้ร้องขอการโอนเงิน โดยจะเป็นตาม url request ดังนี้
Method:POST
Url example-bank.com/tranfer-money
Body : { from: “ A ”, to: “ B ”,amount: 2000 }
หมายความว่าเจ้าของแอคเคาท์ ( หรือ แอคเคาท์ A ) ต้องการโอนเงินไปให้ แอคเคาท์ B จำนวนเงิน 2,000 บาท ทาง server ก็จะทำงานตามที่ผู้ใช้งานคนนี้ร้องขอเพราะเขามีสิทธิตาม session ที่ส่งไป
โดย ผู้ไม่หวังดีวางแผนที่จะให้แอคเคาท์ A โอนเงินไปหาแอคเคาต์เขา ( แอคเคาท์ Z ) เขาได้ทำการส่งอีเมล์หลอกลวงไปหา ผู้ใช้งานแอคเคาต์ A ว่ามีเงินแจกเข้าหาบัญชีของคุณ เพื่อยืนยันสิทธิ์นั้น โปรดคลิกลิ้งก์นี้!! เมื่อ ผู้ใช้งานคนนี้อ่านแล้วหลงเชื่อทำการกดลิงค์นั้นไป โดยลิ้งค์ของผู้หลอกลวงจะทำงานดังนี้ จะเป็นสคริปต์ที่เป็น
Method:POST
Url example-bank.com/tranfer-money
Body : {from: “ A ”, to: “ Z ”,amount: 9999999}
เพียงเท่านี้ผู้ไม่หวังดีก็ได้เงินไปเต็มๆ 9 ล้านบาท คำถามคือทำไมการโอนเงินนี้ถึงสำเร็จทั้งๆที่ผู้ไม่หวังดีไม่ได้ทำอะไรเพียงแค่หลอกให้ผู้ใช้งานแอคเคาท์ A กดลิ้งค์ เพราะว่า การที่ ผู้ใช้งาน A กดลิ้งค์นั้น หมายความว่า ผู้ใช้งาน A เป็นคนส่ง request ไปหาธนาคารเองทำให้ตัวเบราว์เซอร์ส่ง cookie ที่มีอยู่แล้วส่งไปด้วย เมื่อ server รับ request มา server ก็ตรวจสอบ cookie และเป็น cookie ที่ถูกต้องก็ทำตามที่ request เรียกร้องมาเป็นอันสำเร็จ… ดูน่ากลัวไม่ใช่น้อย เราไปดูวิธีป้องกัน กันเลยดีกว่า
วิธีป้องกัน XSS ตัวร้าย
วิธีการที่ป้องกัน ได้ผลที่ชัวร์และแน่นอนที่สุดในตอนนี้นั่นก็คือการใส่ CSRF Token ไปด้วยในทุก request ที่ทำการส่งไปหา server อ้าว.. แล้วมันต่างกัน cookie token อย่างไร ? ต่างโดยสิ้นเชิงครับ เพราะ ตัว cookie จะถูกเก็บไว้ใน browser stack โดยอัตโนมัติแต่เจ้าตัว CSRF Token จะมาในรูปแบบ htm tag response ซึ่ง front-end หรือหน้าเว็บจะต้องจัดการเอา CSRF ใส่เข้าไปด้วยทุกครั้งที่มีการขอ request และเมื่อลองมองย้อนไปที่เหตุการณ์ข้างต้น เมื่อ ผู้ใช้เผลอคลิกลิ้งค์นั้นไปในรอบนี้ request ที่ส่งขึ้นไปหา server นั้นจะไม่มี CSRF Token ติดขึ้นไปด้วย เพราะว่า ฝั่ง Front-end ไม่ได้จัดการใส่ CSRF Token ไปให้นั่นเอง.
เป็นยังไงบ้างครับ จริงๆแล้วยังมีหลักการป้องกันอีกมากมายที่เราควรตระหนักและนำมาใช้เพื่อให้ application ของเรามีความปลอดภัยมากขึ้น คราวหน้าจะมาป้องกันในรูปแบบใด ติดตามได้เลยครับที่ sennalabs blog