09/10/2018, 23:31

MySQL injection ! Xin chỉ giáo !

Em đang nghiên cứu viết một CMS. dùng php và MySQL. đụng đến vấn đề này thì em hơi ngại.
Việc phòng tránh injection sử dụng các hàm php thì cũng đơn giản nhưng MySQL thì em chưa hiểu kĩ bản chất của nó.

Xin ví dụ: em làm một trang đăng nhập có username và password.
khi em đăng nhập.
bên trên server:
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "select username, password from user where username = $username and password = $password";
với lệnh này thì hacker có thể attach sql của họ lên server của mình.
Với lỗi này thì tạo một bộ lọc thì đơn giản thôi

Nhưng điều em muốn hỏi các bác là làm sao mà ứng với lỗi SQL trên mà mấy bọn hacker nó lấy được thông tin của table. bao gồm cả các table name và các colum của CSDL mình.
Câu lệnh nào thực hiện được điều này. Mong các bác chỉ dùm cho, em chưa biết gì nhiều về MySQL. chỉ biết chút đỉnh php và tập tành php thôi.

Bên MS SQL Server thì với lỗi trên thì hacker có thể dùng lệnh này để lấy nội dung của table
select username, password from user where username = 'tien' and password = 'aaa' and 1=convert(int,(select top 1 '||'+table_name+'||' from information_schema.tables where table_name not in (')))--sp_password;

Với câu lệnh này thì bọn hacker có thể lấy toàn bộ nội dung các table của mihnh.
Nhưng bên MySQL thì không làm điều đó được.
Vậy ứng với những câu lệnh nào thì mình thực hiện được điều này trong mysql.

Em không phải là hackser đâu ! Các bác đừng nghĩ bậy ! Tội nghiệp em !
Mong các bác chỉ giáo vơi !
conan1212 viết 01:48 ngày 10/10/2018
Cái này có ai bít hok chỉ Conan với, cũng muốn trở lại học hack nữa nì
pcdinh viết 01:41 ngày 10/10/2018
MySQL từ bản 4.1 trở lên cũng có information schema. Muốn lấy password của admin thì dùng cơ sở dữ liệu mysql cơ chứ nó không nằm trong database information_schema. Nhưng pass ở đó mã hóa 1 chiều chẳng giống ai tới 41 kí tự. Lấy xong cũng chẳng làm gì.
thienthan36 viết 01:46 ngày 10/10/2018
Biết là như thế nhưng nếu một site nào mà mình chưa biết cấu trúc csdl của nó thì làm sao mà mình có thể làmd được.
pcdinh viết 01:32 ngày 10/10/2018
Trong MySQL nó có 2 database mặc định là information_schema và mysql. Trừ khi thằng root nó không grant priv. cho mình access vào 2 db này còn không thì lúc nào chẳng có nó nằm sẵn ở đó.

Query vào được information_schema thì lôi ra được tất cả các table hay db khác.
conmalele viết 01:43 ngày 10/10/2018
If you use a database library that offers support for bound parameters or placeholders (PEAR:B, PDO, etc.), you can enjoy an extra layer of protection. For example, consider the following query using PEAR:B:

<?php
$sql = 'INSERT
INTO user (last_name)
VALUES (?)';
$dbh->query($sql, array($clean['last_name']));
?>



Because the data cannot directly manipulate the format of the query, the risk of SQL injection is mitigated. PEAR:B automatically escapes and quotes the data according to the requirements of your database, so your responsiblity is reduced to filtering input.

If you use bound parameters, your data never enters a context where it is considered anything other than data. This removes the necessity of escaping, although you can consider the escaping to be a step that essentially does nothing (if you prefer to stick to the habit of always escaping output) because there are no characters that need to be represented in a special way. Bound parameters offer the strongest protection against SQL injection.
Có ai biết nó chống cách nào mà hay vậy không?
jiSh@n viết 01:39 ngày 10/10/2018
Quote Được gửi bởi conmalele View Post
Có ai biết nó chống cách nào mà hay vậy không?
Chris Shiflett nói rõ thế rồi mà còn hỏi đánh đố à
pigeeken viết 01:37 ngày 10/10/2018
Bạn dùng thử PDO của PHP thử xem . . . Mình cũng ứng dụng thử SDO và PDO, chạy tốt . . .
babyinternet viết 01:36 ngày 10/10/2018
Tôi nghĩ các bác làm phức tạp hóa vấn đề ra nhiều rồi.. Tôi thì làm đơn giản thôi:
Step1: Lấy user và pass, lọc bỏ một số kí tự nguy hiểm.
##################################################
$username=anti_sql_inj(trim($_POST["username"]));
$username=anti_sql_inj(trim($_POST["username"]));
function anti_sql_inj(){
// cái này các bác tự viết nhé, hoặc em sẽ post sau nếu có ai đó yêu cầu
}
###############################################

Step2: Lấy thông tin từ data
###############################################
SELECT username, password FROM USER WHERE username='$username'
###############################################

Step3: kiểm tra
###############################################
$login = login_check($username,$password);
###############################################

Hàm login_check() trả về 1 trong 3 giá trị:
1. true nếu pass và username trùng với dữ liệu lấy từ data
2. false nếu pass không trùng.
3. -1 nếu username không tồn tại trong data.

Cách này sẽ hạn chế show các table (hàm kiểm tra chỉ trả về true, false hoặc -1 và không show dữ liệu), hạn chế so sánh trực tiếp dữ liệu bằng câu lệnh SQL.
Ngu kiến của em đó
pigeeken viết 01:34 ngày 10/10/2018
^.^ nếu bạn coding kỹ, filter hay validation tất cả request từ client lên thì quá tốt roài ^.^
Bài liên quan
0