0

My code working fine , but i got this error :

SQLSTATE[HY000]: General error

I searching on google and someone say that it's may SQLi
What is this ? And how can i fix that ?
thanks and sorry for my poor english

    try{
        $db_con = new PDO("mysql:host={$db_host};dbname={$db_name}",$db_user,$db_pass);
        $db_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        // Anti Brute Forced
        $stmt = $db_con->prepare("
            SELECT * FROM users
        ");
        $stmt->execute();
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
            $users_username = $row["users_username"];
            $users_password = $row["users_password"];
            $users_wrong_password = $row["users_wrong_password"];
            if ($users_wrong_password <= 3 && isset($_GET["username"],$_GET["password"]) && $_GET["username"] == $users_username && $_GET["password"] != $users_password){
                $u = $users_wrong_password + 1;
                $g = 0;
                $g = $_GET['username'];
                $stmt = $db_con->prepare("
                    UPDATE users
                    SET users_wrong_password = $u
                    WHERE users.users_username = '$g'
                ");
                $stmt->execute();
            }
            if ($_GET["username"] == $users_username && $users_wrong_password >= 4){
                echo "Your Account Was Banned For 1 Hours";
                die;
            }
        }
        $g = $_GET['username'];
        $stmt = $db_con->prepare("SELECT * FROM users where users_username = '$g'");
        $stmt->execute();
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
            $ss = $row["users_wrong_password"];
        }
        if($ss <= 3){
            $g = 0;
            $g = $_GET['username'];
            $stmt = $db_con->prepare("
                UPDATE users
                SET users_wrong_password = 0
                WHERE users_username = '{$_GET['username']}'
            ");
            $stmt->execute();
        }
        // Anti Brute Forced

[Solved] Edit:

  $g = $_GET['username'];
  $p = $_GET['password'];
  $stmt = $db_con->prepare("
   SELECT * FROM users where users_username = '$g' and users_password = '$p'
  ");
Joel
  • 47
  • 1
  • 1
  • 8
  • 1
    First try to find out at witch point the error is thrown – JustOnUnderMillions Apr 05 '17 at 12:50
  • For starters, did you assign anything to those variables in the first line? – Funk Forty Niner Apr 05 '17 at 12:51
  • Your script is at risk of [SQL Injection Attack](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) Have a look at what happened to [Little Bobby Tables](http://bobby-tables.com/) Even [if you are escaping inputs, its not safe!](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) Use [prepared parameterized statements](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) – RiggsFolly Apr 05 '17 at 12:51
  • it's first line, – Joel Apr 05 '17 at 12:52
  • Plus, since you're checking for what seems to be a particular record; you query needs a `WHERE` clause in the first query. – Funk Forty Niner Apr 05 '17 at 12:52
  • 3
    WHATS THE POINT of preparing a query that you have concatenated a $_GET value into DUH. Closing the stable door after the horse has bolted I believe is an appropriate term – RiggsFolly Apr 05 '17 at 12:52
  • you shouldn't be playing around with db stuff using plain text passwords neither. Now I have a feeling what you're going to say: *"It's not going live, it's just a personal project"*; am I right when I say this? – Funk Forty Niner Apr 05 '17 at 12:53
  • There is also little point preparing a query that has no parameters, unless you intend to run it more than once in this session. – RiggsFolly Apr 05 '17 at 12:54
  • ops, i'll try to use WHERE clause – Joel Apr 05 '17 at 12:54
  • not work at all :( – Joel Apr 05 '17 at 12:55
  • What are u trying to achieve @Joel – Masivuye Cokile Apr 05 '17 at 12:55
  • 1
    Use positional `?` or named `:xxx` parameters and dont maually concatenate anything – RiggsFolly Apr 05 '17 at 12:56
  • this error show when user try to brute password , – Joel Apr 05 '17 at 12:56
  • Actually now I have read the code. You dont get all users and compare the password, You get the specific user identified by the UserName and then compare one user with one password – RiggsFolly Apr 05 '17 at 12:57
  • 1
    PHP provides [`password_hash()`](http://php.net/manual/en/function.password-hash.php) and [`password_verify()`](http://php.net/manual/en/function.password-verify.php) please use them. And here are some [good ideas about passwords](https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet) If you are using a PHP version prior to 5.5 [there is a compatibility pack available here](https://github.com/ircmaxell/password_compat) – RiggsFolly Apr 05 '17 at 12:58
  • username=test&password=testa ( wrong password : show HY000 error) – Joel Apr 05 '17 at 12:58
  • thanks RiggsFolly :* – Joel Apr 05 '17 at 12:59
  • $db_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Anti Brute Forced $g = $_GET['username']; $p = $_GET['password']; $stmt = $db_con->prepare(" SELECT * FROM users where users_username = '$g' and users_password = '$p' "); – Joel Apr 05 '17 at 12:59

2 Answers2

2

I found this problem in a similar another way

"errorInfo":["HY000"]

How does "HY000" error happen?

It happens when you are updating, deleting or inserting data with PDO, and you try to fetch it's result.

The solution, just do not use fetch or fetchAll methods after executing an updating, deleting or inserting. Surely, it does not make sense to fetch it's result!

Example:
        $stmt = $db_con->prepare("
            UPDATE users SET name = 'Renato' WHERE ID = 0
        ");
        $stmt->execute();
        $stmt->fetch(PDO::FETCH_ASSOC); // The mistake is here, just remove this line
        $stmt->fetchAll(PDO::FETCH_ASSOC); // It will cause troubles too, remove it

Solving the problem in a loop

The solution is changing the statement variable name inside loop, or fetch all before starting loop:

Solution: Changing variable name

        $stmt = $db_con->prepare("
            SELECT * FROM users
        ");
        $stmt->execute();

        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
                // ...
                // This is another statment
                $another_stmt = $db_con->prepare("
                    UPDATE users
                    SET users_wrong_password = $u
                    WHERE users.users_username = '$g'
                ");
                $another_stmt->execute();
        }

Solution: Fetch all data from query before loop

        $stmt = $db_con->prepare("
            SELECT * FROM users
        ");
        $stmt->execute();
        
        // Everything is fetched here
        $results = $stmt->fetchAll(PDO::FETCH_ASSOC)
        foreach($results as $row){ // Another way to loop through results
                $stmt = $db_con->prepare("
                    UPDATE users
                    SET users_wrong_password = $u
                    WHERE users.users_username = '$g'
                ");
                $stmt->execute(); // Be happy with no troubles
        }
1

I think there are multiple preparations of the same query. Solution Get the query preparation out of the while.

code:

//... your code 
$stmt1 = $db_con->prepare("
         UPDATE users
         SET users_wrong_password = $u
         WHERE users.users_username = '$g'
");

$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
     $users_username = $row["users_username"];
     $users_password = $row["users_password"];
     $users_wrong_password = $row["users_wrong_password"];
     if ($users_wrong_password <= 3 && isset($_GET["username"],$_GET["password"]) && $_GET["username"] == $users_username && $_GET["password"] != $users_password){
                        $u = $users_wrong_password + 1;
                        $g = 0;
                        $g = $_GET['username'];
    $stmt1->execute();
    //...
}
Jose Marques
  • 748
  • 1
  • 6
  • 22