Mã của bạn có biến $username
ở phần trên cùng của câu hỏi, nhưng sau đó bạn có $user
ở phần dưới cùng.
Có lẽ bạn muốn sử dụng cùng một biến?
$username = ($_GET ['user']);
$sth = $dbh->query( "SELECT username, user_state, last_activity, alerts_unread, conversations_unread, message_count
FROM xf_user WHERE username='$user'" );
// ^^ Should this ALSO be $username ?
$row = $sth->fetch();
Chỉnh sửa:Được rồi, bây giờ bạn thật dễ thương với PDO::ATTR_EMULATE_PREPARES
của mình . Quan sát điều này:
Cơ sở dữ liệu và cấu trúc bảng:
Database changed
mysql> show tables
-> ;
+----------------+
| Tables_in_prep |
+----------------+
| users |
+----------------+
1 row in set (0.00 sec)
mysql> select * from users;
+----+---------+--------+
| id | userid | pass |
+----+---------+--------+
| 1 | Fluffeh | mypass |
+----+---------+--------+
1 row in set (0.00 sec)
Và một số mã PHP được sao chép từ mã của bạn, với thuộc tính PDO được thêm vào:
<?php
//$username = ($_GET ['user']);
$username="Fluffeh";
$dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example');
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$sth = $dbh->query( "SELECT userid, pass FROM users WHERE userid='$username'" );
echo "Trying to use $username.\n";
print_r($sth->fetch());
echo "----------------------------------------\n\n";
?>
<?php
//$username = ($_GET ['user']);
$username="user2693017";
$dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example');
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$sth = $dbh->query( "SELECT userid, pass FROM users WHERE userid='$username'" );
echo "Trying to use $username.\n";
print_r($sth->fetch());
echo "----------------------------------------\n\n";
?>
<?php
//$username = ($_GET ['user']);
$username="Oh my' or 1=1 or 'm=m";
$dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example');
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$sth = $dbh->query( "SELECT userid, pass FROM users WHERE userid='$username'" );
echo "Trying to use $username.\n";
print_r($sth->fetch());
echo "----------------------------------------\n\n";
?>
<?php
//$username = ($_GET ['user']);
$username="(select id from users limit 1)";
$dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example');
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$sth = $dbh->query( "SELECT userid, pass FROM users WHERE id='$username'" );
echo "Trying to use $username.\n";
print_r($sth->fetch());
echo "----------------------------------------\n\n";
?>
<?php
//$username = ($_GET ['user']);
// Changed this one to be a non-string, you might be checking an ID instead.
$username="(select id from users limit 1)";
$dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example');
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$sth = $dbh->query( "SELECT userid, pass FROM users WHERE id=$username" );
echo "Trying to use $username.\n";
print_r($sth->fetch());
echo "----------------------------------------\n\n";
?>
<?php
//$username = ($_GET ['user']);
$username="bob'; drop table users; \
";
// This one is tricker to do in PHP code. I could easily enter this into a text field however.
$dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example');
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
//$sth = $dbh->query( "SELECT userid, pass FROM users WHERE id='$username'" );
echo "Trying to use $username.\n";
print_r($sth->fetch());
echo "----------------------------------------\n\n";
?>
Và đầu ra:
Trying to use Fluffeh.
stdClass Object
(
[userid] => Fluffeh
[pass] => mypass
)
----------------------------------------
Trying to use user2693017.
----------------------------------------
Trying to use Oh my' or 1=1 or 'm=m.
stdClass Object
(
[userid] => Fluffeh
[pass] => mypass
)
----------------------------------------
Trying to use (select id from users limit 1).
----------------------------------------
Trying to use (select id from users limit 1).
stdClass Object
(
[userid] => Fluffeh
[pass] => mypass
)
----------------------------------------
Trying to use bob'; drop table users; \
.
----------------------------------------
Ồ, lý do tôi để lại cái cuối cùng cho đến CUỐI CÙNG là kết quả này hiện đã có trong cơ sở dữ liệu của tôi:
mysql> show tables;
Empty set (0.00 sec)
Vâng, đúng vậy, tôi vừa đánh rơi một cái bàn. Để tôi nói lại lần nữa, tôi đã có một câu lệnh chọn lọc, và với một thủ thuật nhỏ, tôi đã nhập một giá trị mà BẤT CỨ AI có nửa bộ não và một số mục đích xấu có thể thực hiện vào trường văn bản và XÓA BẢNG CỦA BẠN.
Bây giờ, đã được chấp nhận, nếu bạn đang thiết lập mọi thứ đúng cách, bạn cũng có thể thiết lập một người dùng khác cho các câu lệnh select và chỉ cấp cho họ select
quyền từ cơ sở dữ liệu của bạn, để ngăn chặn loại điều này xảy ra - nhưng hãy thành thật mà nói ... bạn không phải là bạn?
Rõ ràng đặt ra rằng thi đua là không đủ. Nghiêm túc mà nói, bây giờ VUI LÒNG thực hiện đọc câu trả lời đó , sử dụng các câu lệnh đã soạn sẵn và sử dụng các tham số nếu bạn muốn bảo mật mã của mình.