0

I have created a form with username and password and login button in html. I have created code for php but it is not able to check the condition for login successfull, below is the php code. It is satisfying all conditions except for login successfull. I guess there is some simple mistake in it and i am not able to find it, please help me.

<?php
        include_once('db.php'); 

        $username = mysql_real_escape_string( $_POST["username"] );
        $password = mysql_real_escape_string( md5($_POST["pass"]) );

        if( empty($username) || empty($password) )
            echo "Username and Password Mandatory ";
        else
        {
        $sql = "SELECT count(*) FROM users WHERE( username='$username' AND password='$password')";


        $res = mysql_query($sql);
        $row = mysql_fetch_array($res);

        if( $row[0] > 0 )
         echo "Login Successful";
        else
         echo "Failed To Login";
        }       
?>
chris85
  • 23,846
  • 7
  • 34
  • 51
Hara
  • 77
  • 1
  • 10
  • So you get `Failed To Login` every time? You shouldn't use `mysql_`, nor `md5`. These both are out of date. – chris85 Jul 28 '17 at 14:28
  • **Never store plain text passwords!** Please use ***PHP's [built-in functions](http://jayblanchard.net/proper_password_hashing_with_PHP.html)*** to handle password security. If you're using a PHP version less than 5.5 you can use the `password_hash()` [compatibility pack](https://github.com/ircmaxell/password_compat). ***It is not necessary to [escape passwords](http://stackoverflow.com/q/36628418/1011527)*** or use any other cleansing mechanism on them before hashing. Doing so *changes* the password and causes unnecessary additional coding. – Jay Blanchard Jul 28 '17 at 14:29
  • ***Please [stop using `mysql_*` functions](http://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php).*** [These extensions](http://php.net/manual/en/migration70.removed-exts-sapis.php) have been removed in PHP 7. Learn about [prepared](http://en.wikipedia.org/wiki/Prepared_statement) statements for [PDO](http://php.net/manual/en/pdo.prepared-statements.php) and [MySQLi](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) and consider using PDO, [it's really pretty easy](http://jayblanchard.net/demystifying_php_pdo.html). – Jay Blanchard Jul 28 '17 at 14:29
  • [Little Bobby](http://bobby-tables.com/) says ***[your script is at risk for SQL Injection Attacks.](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)***. Even [escaping the string](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) is not safe! – Jay Blanchard Jul 28 '17 at 14:29
  • Thanks for updating me, can you let me know what will be the equivalent code in PDO for above login code – Hara Jul 28 '17 at 14:41
  • @JayBlanchard Maybe the code has been edited since your comment, but the password isn't stored in plain text, it's *hashed* as a MD5 from the POST. I know it's even worse than SHA1/256, but still better than plain text. – Sarkouille Jul 28 '17 at 14:48
  • yes I am using MD5 to store password, i am just learning things in PHP. Can you please post code using PDO for tha same. – Hara Jul 28 '17 at 14:53
  • 1
    _"Can you please post code"_ The links already posted have many great examples. Please read them. – Alex Howansky Jul 28 '17 at 15:05
  • you must use mysql_num_rows($sql) function – Saquib Lari Jul 28 '17 at 15:17
  • ***You really shouldn't use [MD5 password hashes](http://security.stackexchange.com/questions/19906/is-md5-considered-insecure)*** @ksjohn – Jay Blanchard Jul 28 '17 at 15:24

2 Answers2

-2

Propably, you have to use the following command instead of $row[0] > 0:

mysql_num_rows($sql)

You can check the user like this:

if(mysql_num_rows($res)==1)
  echo "Login Successful";
} else {
  echo "Failed To Login";
}
Julian Schmuckli
  • 3,681
  • 11
  • 37
  • 64
  • Turn the tide against teaching/propagating sloppy and dangerous coding practices. If you post an answer without prepared statements [you may want to consider this before posting](http://meta.stackoverflow.com/q/344703/). Additionally [a more valuable answer comes from showing the OP the right method](https://meta.stackoverflow.com/a/290789/1011527). – Jay Blanchard Jul 28 '17 at 14:31
  • Actually, what the OP is doing is correct since they are returning a count with the query. Your answer doesn't change that. – Jay Blanchard Jul 28 '17 at 14:34
  • @JayBlanchard I agree with you. But as I mentioned, it 'could' be a solution for his problems. – Julian Schmuckli Jul 28 '17 at 14:39
  • 3
    Worse still, if you use the existing SQL (the OP's count) and there is a count of 0, it is still a result. And hence you'll get one row. Therefore you'll always have a successful login. Doh. – Progrock Jul 28 '17 at 14:41
  • **Please**, don't use `mysql_*` functions for new code. They are no longer maintained and the community has begun the [deprecation process](http://news.php.net/php.internals/53799), and `mysql_*` functions have been officially removed in PHP 7. Instead you should learn about [prepared statements](https://en.wikipedia.org/wiki/Prepared_statement) and use either `PDO` or `mysqli_*`. If you can't decide, [this article will help to choose your best option](http://php.net/manual/en/mysqlinfo.api.choosing.php). - I also assume your going to get downvoted for propagating – GrumpyCrouton Jul 28 '17 at 16:13
-2

You should directly check if the output of mysql_fetch_array() is not null nor false :

    $res = mysql_query($sql);
    if( $row = mysql_fetch_array($res) )
     echo "Login Successful";
    else
     echo "Failed To Login";
    } 

Regarding you overall code, there a some things that are clearly bad practices :

  • mysql_* functions are deprecated since PHP5.5 and don't even exist since PHP7.0. Use the Mysqli class or PDO instead.
  • Don't use MD5 to hash your users passwords, it's broken for years and years. Add salt for a better protection.
  • Don't close you php tags. It's optional, and it will give you headaches if you try to include a php file that has a closing tag at the end.

That code is better :

<?php

include_once('db.php'); 

if( empty($_POST['username']) || empty($_POST['password']) ) 
    echo "Username and Password Mandatory ";
else {
    try {
        $db = new PDO("mysql:host=$dbHostname;dbname=$basename", $dbUsername, $dbPassword);
        $stmt = $db->prepare("SELECT * FROM users WHERE username = username AND password = password");
        $stmt->bindParam(':username', $_POST['username']);
        $stmt->bindParam(':password', md5($_POST['password']));  // I still urge you to pick a valid hash function ! This one is broken for ages !
        $stmt->execute();
    } catch (PDOException $e) {
        print "Erreur !: " . $e->getMessage() . "<br/>";
        die();
    }
    if (empty($row))
        echo "Failed To Login";
    else
        echo "Login Successful";
} 
Sarkouille
  • 1,275
  • 9
  • 16
  • what is this line $db->real_connect($dbHostname, $dbUsername, $dbPassword, $basename, $dbPort); i already included the db details in db.php – Hara Jul 28 '17 at 15:11
  • In order to use the class to execute a query, you have to connect to the db. I put added the line at the right place so that you don't miss that part. You are free to move this line and the line right above in another file if you feel that way, it was simply more rigorous to give you the whole process. – Sarkouille Jul 28 '17 at 15:13
  • can i use like this $db->real_connect('db.php'); – Hara Jul 28 '17 at 15:16
  • No. `'db.php'` is a string corresponding with a file's name. You need to insert the right informations in the right order : http://php.net/manual/fr/mysqli.real-connect.php – Sarkouille Jul 28 '17 at 15:18
  • Double doh. See this: https://stackoverflow.com/questions/45375948/login-form-php-code#comment77714063_45376070 – Progrock Jul 28 '17 at 15:26
  • Turn the tide against teaching/propagating sloppy and dangerous coding practices. If you post an answer without prepared statements [you may want to consider this before posting](http://meta.stackoverflow.com/q/344703/). Additionally [a more valuable answer comes from showing the OP the right method](https://meta.stackoverflow.com/a/290789/1011527). – Jay Blanchard Jul 28 '17 at 15:27
  • i tried using $db->real_connect("localhost", "dbusername", "password", "dbname"); it seems not connecting to db – Hara Jul 28 '17 at 15:27
  • Hint: `if([0]) { echo 'Oops'; }` – Progrock Jul 28 '17 at 15:30
  • @Haraharamahadev Use correct values instead and it should work. – Sarkouille Jul 28 '17 at 15:33
  • @JayBlanchard I've taken the time to read the resources you linked in your comment, so I'm interested in knowing why you give me advice material regarding rewriting dangerous mysql code so that is uses PDO or mysqli, since I did exactly that, namely rewriting the code so that it uses mysqli. – Sarkouille Jul 28 '17 at 15:35
  • @ksjohn Escaping is no longer best practices. Parameterizing queries is what should be taught and used today. – chris85 Jul 28 '17 at 15:54
  • You rewrote it using MySQLi but didn't use prepared statements (escaping the string is not enough, folks can get around that). I'll leave password security alone for the moment. – Jay Blanchard Jul 28 '17 at 16:01
  • @ksjohn the else condition is not at all working. Can you please recheck it, based on this learning i am trying to change all my mysql_* to mysqli – Hara Jul 28 '17 at 16:09
  • Lost a +1 for not using prepared statements :( Please don't introduce new insecure code to people who don't know any better – GrumpyCrouton Jul 28 '17 at 16:16