Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

PDO - Lỗi nghiêm trọng:Gọi hàm thành viên fetch () trên một đối tượng không phải

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Giữ nhiều mục trong một cột trên mysql

  2. Sử dụng PHP để tải tệp lên và thêm đường dẫn đến cơ sở dữ liệu MySQL

  3. Sử dụng múi giờ trong ứng dụng web PHP

  4. mysql GROUP_CONCAT trùng lặp

  5. đối sánh mysql với nhiều từ