Saturday, May 16, 2009

SQL Injection

หมายถึง แฮกเกอร์สามารถที่จะแทรก Malicious Code หรือ คำสั่งที่แฮกเกอร์ใช้ในการเจาะระบบส่งผ่าน Web Application ไปยังระบบภายนอกที่เราเชื่อมต่ออยู่ เช่น ระบบฐานข้อมูล SQL โดยวิธี SQL Injection หรือ เรียก External Program ผ่าน shell command ของระบบปฎิบัติการ เป็นต้น

ส่วนใหญ่แล้วแฮกเกอร์จะใช้วิธีนี้ในช่วงการทำ Authentication หรือการ Login เข้าระบบผ่านทาง Web Application เช่น Web Site บางแห่งชอบใช้ "/admin" ในการเข้าสู่หน้า Admin ของ ระบบ ซึ่งเป็นช่องโหว่ให้แฮกเกอร์สามารถเดาได้เลยว่า เราใช้ http://www.mycompany.com/admin ในการเข้าไปจัดการบริหาร Web Site ดังนั้นเราจึงควรเปลี่ยนเป็นคำอื่นที่ไม่ใช่ "/admin" ก็จะช่วยได้มาก

วิธีการทำ SQL injection ก็คือ แฮกเกอร์จะใส่ชื่อ username อะไรก็ได้แต่ password สำหรับการทำ SQL injection จะใส่เป็น Logic Statement ยกตัวอย่างเช่น ' or '1' = '1 หรือ " or "1"= "1

ถ้า Web Application ของเราไม่มีการเขียน Input Validation ดัก password แปลกๆ แบบนี้ แฮกเกอร์ก็สามารถที่จะ bypass ระบบ Authentication ของเราและ Login เข้าสู่ระบบเราโดยไม่ต้องรู้ username และ password ของเรามาก่อนเลย

วิธีการเจาะระบบด้วย SQL injection ยังมีอีกหลายแบบจากที่ยกตัวอย่างมา ซึ่งแฮกเกอร์รุ่นใหม่สามารถเรียนรู้ได้ทางอินเทอร์เน็ตและวิธีการทำก็ไม่ยาก อย่างที่ยกตัวอย่างมาแล้ว

วิธีการป้องกัน

นักพัฒนาระบบ (Web Application Developer) ควรจะระมัดระวัง input string ที่มาจากทางฝั่ง Client (Web Browser) และไม่ควรใช้วิธีติดต่อกับระบบภายนอกโดยไม่จำเป็น

ควรมีการ "กรอง" ข้อมูลขาเข้าที่มาจาก Web Browser ผ่านมาทางผู้ใช้ Client อย่างละเอียด และ ทำการ "กรอง" ข้อมูลที่มีลักษณะที่เป็น SQL injection statement ออกไปเสียก่อนที่จะส่งให้กับระบบฐานข้อมูล SQL ต่อไป

การใช้ Stored Procedure หรือ Trigger ก็เป็นทางออกหนึ่งในการเขียนโปรแกรมสั่งงานไปยังระบบฐานข้อมูล SQL ซึ่งมีความปลอดภัยมากกว่าการใช้ "Dynamic SQL Statement " กับฐานข้อมูล SQL ตรงๆ

การใช้ Prepare Statement
การส่งตัวแปรไปยัง statement โดยผ่าน jdbc หรือเรียกว่า variable binding ตัวอย่างเช่น
String selectStatement = "SELECT * FROM User WHERE userId = ? ";
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
prepStmt.setString(1, userId);
ResultSet rs = prepStmt.executeQuery();

prepare statement จะช่วยป้องกัน SQL Injection ตัวอย่างถัดไปจะเป็นการส่งตัวแปรไปโดยตรงไปยัง prepare statement

String strUserName = request.getParameter("Txt_UserName");
PreparedStatement prepStmt = con.prepareStatement("SELECT * FROM user WHERE userId = '+strUserName+'");

การใช้ Hibernate
ใน Hibernate ก็จะใช้ propare statement แต่จะยังคงมีปัญหาเกี่ยวกับ injecting HQL statements ซึ่งจะอยู่ในลักษณะของ ORM อีก

No comments: