Web App Security 101 ทำอย่างไรให้เว็บปลอดภัยโปรแกรมเมอร์ต้องรู้
14 มกราคม 2022
แน่นอนว่าปัจจุบันเทรนด์ของการทำเว็บแอปพลิเคชันถือว่าเป็นหนึ่งในกระแสหลักของโลกยุคนี้เลยก็ว่าได้ หากลองดูแล้วแทบจะทุกธุรกรรมที่เกิดขึ้นในชีวิตของเรานั้นก็มักจะอยู่บนเว็บต่าง ๆ ไม่ว่าจะเป็นเรื่องที่ดูเหมือนเล็ก ๆ อย่าง ชื่อ นามสกุล จนไปถึงเรื่องที่จริงจังอย่างเรื่องเงิน ๆ ทอง ๆ
ถึงตรงนี้ใครหลาย ๆ คนที่กำลังจะเริ่มต้นทำเว็บแอปฯ หรือ อยากกระโดดมาทำเว็บแอปฯ อาจจะมีความคิดในใจว่า “จริง ๆ แล้วงานที่เราจะเริ่มทำนี้เป็นเพียงแค่ Project เล็ก ๆ เอง ขอแค่มันทำงานได้ก็น่าจะพอแล้วมั้ง”
แต่จริง ๆ แล้วไม่ใช่เลย เพราะในปัจจุบัน เรื่องของความปลอดภัยบนโลก Cyber นั้นถือว่าเป็นเรื่องที่สำคัญมาก เพราะแค่อีเมลของคุณได้หลุดไป หรือ รหัสผ่านของคุณ (ที่แม้ว่าจะมีการเข้ารหัสให้คนทั่วไปอ่านไม่ออกแล้วก็ตาม) หลุดไป สามารถนำไปทำอะไรไม่ดีต่อได้อีกเพียบ
โอเค เพื่อไม่ให้เป็นการเสียเวลา เราลองมาดูเช็คลิสต์พื้นฐานที่จะทำให้เว็บแอปฯ ของเราปลอดภัยกันก่อนดีกว่า โดยตัวนี้ดึงมาจาก OWASP Secure Coding Checklist ที่มีประโยชน์มาก ๆ
ด้านการตรวจสอบข้อมูลที่รับเข้ามาในระบบ (Input Validation)
- ไม่เชื่อใจในข้อมูลที่ถูก Input เข้าสู่ระบบ และ ไม่ควรตรวจสอบ Input ที่รับเข้ามาของฝั่ง Client เพียงอย่างเดียว ควรดูฝั่ง Server ด้วย
- กำหนดขอบเขต ขนาด และ ประเภทของข้อมูลที่ถูกนำเข้ามาทุกครั้ง
- ทำการ Validate ตรวจสอบข้อมูลทั้งหมดที่ถูกส่งมาจาก Client / User ก่อนทำการประมวลผล ไม่ว่าจะเป็น URLs, HTTP Header จนถึง Embeded Code ต่าง ๆ
ด้านการตรวจสอบข้อมูลที่ Output ออกไป (Output Encoding)
- ทำการ Validate ตรวจสอบข้อมูลบนระบบที่เชื่อถือได้ และ ปลอดภัย
- ป้องกันการทำงานของคำสั่งที่ถูกสั่งให้ทำงานโดยผู้ไม่หวังดีด้วยการ Encoding
ด้านการยืนยันตัวตน และ การจัดการรหัสผ่าน (Authentication & Password Management)
- ต้องให้มีการ Authentication สำหรับการเข้าถึงทุกข้อมูลในระบบตามหลักการ CIA TRIAD ที่เป็นพื้นฐานด้านความปลอดภัย
- ต้องมีการป้องกันการใช้รหัสผ่านซ้ำ (สังเกตได้ว่าเว็บไซต์ของหน่วยงานขนาดใหญ่หลายเว็บจะมีการขึ้นแจ้งเตือนว่าเราใช้รหัสซ้ำกับเมื่อหลายเดือน หรือ ปีก่อน)
- ส่งข้อมูลแจ้ง User ทุกครั้งที่รหัสถูกเปลี่ยนแปลง
- มีการรายงานจำนวนครั้งที่ไม่สามารถเข้าสู่ระบบได้ เมื่อผู้ใช้งานท่านนั้นเข้าสู่ระบบสำเร็จ
ด้านการจัดการ และ ใช้งานเซสชัน (Session Management)
- ทั้ง Sessions และ Connection ต้องถูกทำลายทิ้งเมื่อผู้ใช้งานลงชื่อออกจากระบบ
- ควรมีการป้องกันการเข้าสู่ระบบจากหลายแหล่งพร้อมกัน สำหรับผู้ใช้งานคนเดียวกัน ทั้งนี้อาจขึ้นกับโมเดล ลักษณะทางธุรกิจของเว็บแอปของเรา
ด้านสิทธิ์การเข้าถึงข้อมูล (Access Control)
- ข้อมูลภายในระบบ หรือ ของผู้ใช้, URLs จนไปถึง บริการต่าง ๆ ที่มีการกำหนดสิทธิ์ไว้ จะต้องมีแค่ User ที่มีสิทธิ์ในการเข้าถึงได้เท่านั้น
- ควรมีมาตราการตรวจสอบบัญชีในระบบ และ มีการลบบัญชีที่ไม่ได้ใช้งาน
- กรณีที่มีบัญชีเชื่อมโยงกับระบบอื่น ๆ ทั้งภายใน หรือ ภายนอก และ ไม่ได้ทำงานหลัก ควรให้สิทธิ์ในการเข้าถึงข้อมูลน้อยที่สุด
- ควรมีการกำหนดจำนวน Transaction ที่ User คนหนึ่งสามารถทำได้ในระยะเวลาหนึ่ง
ด้านการจัดการข้อผิดพลาดและเก็บประวัติ (Error Handling & Logging)
- เมื่อเกิด Error ไม่ควรแสดง หรือ โยนข้อมูลในส่วน Debugging ออกมาให้ผู้ใช้งานทั่วไปได้เห็น
- Log ต่าง ๆ ไม่ควรเก็บข้อมูล Sensitive ที่มีความเกี่ยวข้องกับระบบ หรือ Session ต่าง ๆ
- Log สามารถแสดงถึงจำนวนครั้งที่มีการ Input ผิดพลาด, จำนวนครั้งการ Authentication, การแสดงผลส่วน Access Control ตลอดจนไปถึง System Exception และ การเปลี่ยนแปลงข้อมูล หรือ ค่าบางอย่างที่ส่งผลต่อความปลอดภัยของระบบที่ต้องได้รับการดูแล และ ตรวจสอบต่อ
ด้านความปลอดภัยของข้อมูล (Data Protection)
- ไม่ควรขอ หรือ นำข้อมูลที่มีความ Sensitive ไปใส่ไว้กับ GET request
- ให้สิทธิ์การเข้าถึงข้อมูลของแต่ละ User เท่าที่เขาใช้งานเท่านั้น
- ป้องกันการเข้าถึง และ ดู Source Code ของระบบจากภายนอก และ มีการควบคุมการเข้าถึงในส่วนที่สำคัญ หรือ ข้อมูลที่เป็นความลับของระบบ
ด้านการจัดการหน่วยความจำ (Memory Management)
- ควรมีการตรวจสอบ Buffer size เพื่อป้องกันการ Overflow
- ควรหลีกเลี่ยงการใช้ฟังก์ชันที่อาจเกิดช่องโหว่ให้กับระบบได้ เช่น print, strcat หรือ strcpy เป็นต้น
จากข้างต้นก็น่าจะได้รับแนวทางกันไปบ้างแล้ว แต่เอาจริง ๆ ด้านนี้ยังมีข้อมูลให้ศึกษาอีกมากมาย โดยสามารถค้นหาได้จาก OWASP Secure Coding Checklist ที่จะเป็นเหมือน ไกด์ไลน์ ช่วยให้เราพัฒนาระบบให้ปลอดภัยยิ่งขึ้น
ดังนั้นในวันนี้เราจะมาให้ทุกคนได้เข้าใจกับเรื่องความปลอดภัยของเว็บแบบไว ๆ ที่เป็นพื้นฐานที่ทุกคนต้องรู้ไปพร้อมกัน !!
มาเริ่มกับกรณี Classic อย่าง SQL Injection
หนึ่งในกระบวนท่าเบสิคที่สุดของการโจมตีเว็บไซต์ และ แอปพลิเคชันผ่านการเนียนเอาคำสั่งที่ปกติแล้วไว้ใช้กับฐานข้อมูล ใส่แนบไปกับฟอร์ม ช่องกรอกข้อมูลต่าง ๆ ที่อยู่ตามในเว็บของเรา หรือ จนไปถึง Message ต่าง ๆ ที่เอาไว้คุยกับ Web / Application Server
มาดูตัวอย่างแรกกับการใส่คำสั่ง DROP TABLE เพื่อลบตารางฐานข้อมูลในช่องที่ปกติแล้วไว้สำหรับกรอก User id ที่ถือว่าอันตรายมาก ๆ ถ้าหากปล่อยให้ใครก็ได้สามารถลบตารางในฐานข้อมูลของเราได้
กับอีกตัวอย่างการใช้ SQL Injection ในการ By Pass ฟอร์มการเข้าสู่ระบบเพราะคำสั่งเต็ม ๆ ที่ปกติแล้วจะไว้ใช้ในการค้นหา User จะถูกแทนที่ด้วย “ or “”=” ที่พอผสมกับคำสั่งเดิมที่เคยเขียนไว้จะได้ในลักษณะนี้
SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""
ซึ่งผลลัพธ์ที่ได้จะเป็นจริงเสมอ ทำให้อาจเกิดข้อผิดพลาดในการยืนยันตัวตนได้เช่นกัน ถึงแม้ว่ากรณีของ SQL Injection นี้จะเป็นกรณีที่ Classic แต่ผู้ที่เริ่มต้นหันมาทำเว็บแอปฯ ก็เจอได้เหมือนกัน โดยวิธีแก้อาจจะใช้วิธีตั้งแต่การตรวจสอบ Message ที่รับเข้ามา หรือ การทำ string escape ที่เป็นการแปลงข้อความต่าง ๆ ที่รับมาอีกทีอยู่ในรูปแบบของ String หรือ ข้อความจริง ๆ ไม่ให้ใครเอาคำสั่ง SQL มาใส่ได้ หรือ ถ้าใส่ได้ จะต้องไม่ถูกสั่งให้ทำงานนั่นเอง
หรืออีกกรณีก็คือ Cross Site Scripting ที่เจอบ่อยไม่แพ้กัน
โดยเป็นการโจมตีโดยที่มีผู้ไม่หวังดีแอบใส่สคริปต์ลงมาในช่อง ฟอร์มต่าง ๆ ในเว็บไซต์ของเรา เช่น ช่องสำหรับแสดงความคิดเห็น และ เมื่อมีใครซักคนเข้ามาในหน้าดังกล่าว แล้วระบบแสดงรายการความคิดเห็นของผู้ไม่หวังดีนั้นมา สคริปต์ดังกล่าวก็จะถูกสั่งให้ทำงาน (และ แน่นอนว่าวิธีการป้องกันก็จะคล้าย ๆ กับ SQL Injection เช่นกัน ที่ถ้าหากจะแสดงผลอะไรออกมา หรือ จะบันทึกข้อมูลอะไรลงในระบบคือต้องมีการตรวจสอบก่อน
และถ้าถามว่า มีแค่เรื่องนี้หรือเปล่าที่ต้องรู้ คำตอบก็คือ “ไม่ใช่”
มีคำนึงที่ได้ยินมาเสมอสำหรับวงการ Computer Security คือ “สิ่งที่คิดว่ามันปลอดภัย มันอาจจะปลอดภัยแค่ในเฉพาะตอนนี้ แต่อีกหน่อยมันอาจจะไม่ปลอดภัยก็ได้”
ดังนั้นยังมีอีกหลายแง่มุมที่ต้องดูกันต่อ โดยจะมีคำถามด้านความปลอดภัยมากมายอยู่ในแง่มุมต่าง ๆ ที่จะช่วยให้เราได้ตรวจทานระบบให้มี “ความปลอดภัยเพียงพอ” ในการพัฒนา เช่น
มุมมองด้านการยืนยันตัวตนเข้าสู่ระบบ (Authentication) ในส่วนนี้มีหน้าใดที่ไม่ได้ตรวจสอบสิทธิ์การเข้าถึง หรือ มีการปล่อยให้ผู้ที่ไม่มีสิทธิ์เข้าถึง ได้เข้าถึงข้อมูลอะไรหรือไม่ ?, รหัสผ่าน หรือ ข้อมูลที่ควรเป็นความลับถูกเก็บไว้ดีหรือไม่ ? (แน่นอนว่าข้อมูลที่ต้องการความปลอดภัยสูงเช่น Password ไม่ควรเก็บไว้ในเครื่องของ User) จนถึงการขโมย หรือ เจาะ Session ที่อาจถูกสวมสิทธิ์โดยผู้ไม่หวังดี ก็สามารถเกิดขึ้นได้
มุมมองด้านการตั้งค่าระบบ (Misconfiguration) เช่น เราปล่อยให้เว็บของเราที่อยู่ในโหมด Debug ถูกอัปโหลดขึ้นไปบน Production หรือเปล่า ? เพราะถ้าปล่อยไปในส่วนนี้อาจมีข้อมูลบางอย่างหลุดออกไป เช่น Log จนไปถึง ข้อมูลสำคัญของระบบ และ การใช้งาน Software ที่ล้าสมัย ไม่มีการอัปเดตอยู่อย่างสม่ำเสมอ จนถึงเรื่องของรหัสที่เข้าสู่ตัว Server หรือ Database ที่เดาง่าย และ ไม่ได้เปลี่ยนใหม่อยู่ตลอด ในส่วนนี้ผู้ไม่หวังดีอาจจะทำการเดารหัสของคุณไปเรื่อย ๆ ผ่านโปรแกรมที่ถูกเขียนมาได้ ถ้าเราใช้รหัสเดิมอยู่ สักวันหนึ่งจะต้องถูกแกะออกอยู่ดี
และ มุมมองอื่น ๆ เช่น มุมมองด้านการรองรับผู้ใช้งาน ที่อาจเกิดเหตุการณ์ที่ทราฟิกมหาศาลนับล้าน ถูกส่งเข้ามาในเว็บของเรา ให้เราดีใจเล่น ๆ ในตอนแรกว่า Project ของเรากำลังดังพลุแตก แต่จริง ๆ แล้วถูกโปรแกรมส่งมาโจมตีให้เว็บเราล่ม
โดยเทคนิคนี้เราเรียกว่า Denial-of-service (DoS) หรือ Distributed denial-of-service (DDoS) ที่จะเป็นการส่ง Traffic จำนวนมากมายังระบบของเรา ให้ไม่สามารถทำงานต่อได้นั่นเอง ซึ่งประเด็นเหล่านี้ที่ได้กล่าวถึงทั้งหมดในบทความยังถือว่าเป็น “น้ำจิ้ม” เพราะการโจมตีนั้นยังมีอีกมาก
และสุดท้าย ถ้าถามว่ามีสูตรตายตัวไหม ในการทำเว็บให้ปลอดภัย
คำตอบนั้นก็ไม่เกินที่ใครหลายคนคิดคือ “ไม่มี !” เพราะการโจมตีแต่ละแบบก็ต้องรับมือแตกต่างกัน คล้าย ๆ กับ การที่เราไปหาคุณหมอตอนไม่สบาย แต่ละอาการ เชื้อโรคแต่ละตัว ก็ต้องมีวิธีการรักษาที่แตกต่างกัน
แต่เรื่องที่ดูเป็นพื้นฐานที่สุดที่ทำให้เราปลอดภัยในระดับเริ่มต้นก็คือการ “ตรวจสอบทุกอย่างที่เข้ามาในระบบ” “ไม่ปล่อยให้ใครที่ไม่มีสิทธิ์ทำอะไรในสิ่งที่เขาไม่มีสิทธิ์ได้” และ “สิ่งที่ดูเหมือนไม่มีอะไรอย่าง Configuration ของโปรแกรมต่าง ๆ หรือ สิ่งที่เราติดตั้งในระบบก็สามารถกลายเป็นของโหว่ได้” และ ควรหา Firewall ดี ๆ เพื่อป้องกันการโจมตีแต่เนิ่น ๆ
ซึ่งสุดท้ายแล้ว การที่เราในฐานะนักพัฒนาเว็บแอปพลิเคชันทำ และ ควรรู้คือความปลอดภัยพื้นฐาน แต่ถ้าหากต้องการทำให้ปลอดภัยจริง ๆ และ มีงบประมาณซักหน่อย แนะนำให้ควรหาผู้เชี่ยวชาญเฉพาะทาง เพราะ “เงินที่เราลงทุนไปกับความปลอดภัย ถือว่าเป็นมูลค่าน้อยมาก ๆ ถ้าเทียบกับ ทุกอย่าง รวมถึงโอกาสที่เราจะเสียไป กับระบบที่ไม่มีความปลอดภัย
“เหมือนคำโบราณที่บอกไว้ว่า เสียน้อยเสียยาก เสียมากเสียง่ายนั่นแหละครับ”
แถมสุดท้าย ! สำหรับใครที่อยากได้เครื่องมือไปตรวจสอบความปลอดภัยของเว็บแอปพลิเคชันของเรา
ก็มีหลายตัวที่มาแนะนำ เช่น Zed Attack Proxy (ZAP) ตัวนี้ถูกพัฒนาโดย OWASP (Open Web Application Security Project) ที่เป็น Web App Scanner ไว้ทำการตรวจสอบช่องโหว่ให้กับเราได้แบบอัตโนมัติเลยนั่นเอง และที่สำคัญคือฟรี และ เป็น Open Source อีกด้วย ใครสนใจก็สามารถลองใช้งานกันได้ที่เว็บไซต์เขาได้เลยครับ https://www.zaproxy.org/
อ้างอิงข้อมูลจาก
Reference 1 : https://www.cloudflare.com/learning/security/what-is-web-application-security/
Reference 2 : https://www.w3schools.com/sql/sql_injection.asp
Reference 3 : https://www.mindphp.com/บทความ/244-security/5495-cross-site-scripting-xss-hacker-website-security.html
บทความที่เกี่ยวข้อง