แค่อยากจะรู้ ตอน SQL injection

6 02 2009

ลองไปนี่ดูครับ(English)www.acunetix.com/websitesecurity/sql-injection.htm

SQL Injection
คือ การที่ในเวปมีการรับข้อมูลจากผู้ใช้ แล้วนำไปใช้ในการสั่งให้ฐานข้อมูลทำงาน แล้ว ผู้ใช้พยายามที่จะหลอกโปรแกรมให้ทำงานนอกเหนือจากที่เราต้องการ หรือ หลอกให้โปรแกรมทำงานโดยผ่านการตรวจสอบเงื่อนไขบางอย่าง

Injection Flaws

หมาย ถึง แฮกเกอร์สามารถที่จะแทรก 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 หรือ a’ or 1=1–

Query = “SELECT * FROM product WHERE Password=’$input’”;
แต่ผู้ใช้ทำการใส่ ข้อมูลเป็น a’ or 1=1–
ดังนั้น query ที่ได้จะเป้น
Query = “SELECT * FROM product WHERE Password=’a’ or 1=1–’”;
จะเห็นว่าเมื่อนำไช้งานแล้ว จะสามารถเรียกดูข้อมูลได้เสมอ เนื่องจาก 1=1 เป็นจริง

สมมุติว่า มีโค้ดต่อไปนี้ใน application และ parameter “userName” ซึ่งประกอบด้วย
ชื่อผู้ใช้ ช่องโหว่แบบ SQL Injection เกิดขึ้นในโค้ดนี้:

statement := “SELECT * FROM users WHERE name = ‘” + userName + “‘;”

ถ้าป้อน “a’; DROP TABLE users; SELECT * FROM data WHERE name LIKE ‘%”
เข้าไปในส่วน “userName” จะทำให้เกิด SQL statement ต่อไปนี้

SELECT * FROM users WHERE name = ‘a’; DROP TABLE users; SELECT * FROM data WHERE name LIKE ‘%’;

ฐานข้อมูลจะเอ็กซิคิวท์ statement ตามลำดับ คือ select data, drop user table
และ select data ทำให้ผู้ใช้เว็ปสามารถดูหรือแก้ไขข้อมูลใด ๆ ที่อยู่ในฐานข้อมูล
ที่ผู้ใช้ที่เชื่อมโยงกับฐานข้อมูลสามารถอ่าน หรือแก้ไขได้

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

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

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

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

ช่องโหว่แบบ SQL Injection สามารถแก้ไขได้ใน programming language ส่วนใหญ่
ในภาษา Java ควรมีการใช้ PreparedStatement class

แทนที่จะใช้

Connection con = (acquire Connection)
Statement stmt = con.createStatement();
ResultSet rset = stmt.executeQuery(“SELECT * FROM users WHERE name = ‘” + userName + “‘;”);

ให้ใช้โค้ดต่อไปนี้แทน

Connection con = (acquire Connection)
PreparedStatement pstmt = con.prepareStatement(“SELECT * FROM users WHERE name = ?”);
pstmt.setString(1, userName);
ResultSet rset = stmt.executeQuery();


เลือกคำสั่ง

ข้อมูล

3 การตอบรับ

24 02 2009
tehxman

ทำไม เขียนซ้ำแล้วเพิ่มคำวะ ไม่แก้อันเก่า ไม่ก็ลบอันเก่าไป อ่านแล้ว มันแม่งๆ ข้างล่างก็มี

10 03 2009
tor

จากโค้ดนี้ จะแก้ยังไงครับ
<%
if(request.getParameter(“login”)!=null){
String l_username=request.getParameter(“l_username”);
String l_password=request.getParameter(“l_password”);
try{
Class.forName(“com.mysql.jdbc.Driver”);

String url=”jdbc:mysql://localhost:3306/Projectjsp?user=root&password=1234″;
Connection con = DriverManager.getConnection(url);
Statement stmt = con.createStatement();

String sql =”SELECT * FROM customer WHERE c_username=’”+l_username+”‘”;

out.println(“Your Username or Password not correct !!!!!”);

ResultSet rs = stmt.executeQuery(sql);

if (rs.next()){
session.setAttribute(“name”,rs.getString(“c_username”));
response.sendRedirect(“index.jsp”);
}
else{
out.println(“Your Username or Password not correct !!!!!”);
out.println();

}
stmt.close();
con.close();
}catch(Exception w){
out.println(“caught exception” + w);
}
}
%>

UserName
Password

เป็น jsp ครับ

10 03 2009
lengm0

ถ้าเป็น java มีกลไกที่มา support เรื่องนี้อยู่แล้วครับ

ตรงประเด็นนี้เป๊ะเลย

ลองไปดู หรือ ค้นหาผ่าน google ได้เลยครับ มีทั้งภาษไทยและ eng เยอะแยะ

มันชื่อว่าการใช้ prepare statement ครับ

ใส่ความเห็น