0

I stored my session like this :

$_SESSION['user'] = $_POST['u_name'];
$_SESSION['pass'] = $_POST['u_pass'];

Is this secure ?

if( isset($_SESSION['user']) && isset($_SESSION['pass']) ) {

    // user exists

}else{

    // user does not exist

}

Or should I check (in every file) if

  • $_SESSION['user']
  • $_SESSION['pass']

are in database.

Like this :

    // db connection
    $conn = new PDO('mysql:host='.$host.';dbname='.$dbname, $user_db, $pass_db);

    // query string
    $stmt = $conn->prepare("SELECT * FROM users WHERE uname=:u_name AND AES_DECRYPT(upass,'some_key') = :u_pass;");

    // execute
    $statement->execute( array( 'u_name' => $_SESSION['user'], 'u_pass' => $_SESSION['pass']) );

    // does it return something ?
    if( $stmt->fetchColumn() == 1){

        // user exists

    }else{

        // user does not exist

    }
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
David
  • 4,785
  • 7
  • 39
  • 63

3 Answers3

5

No, don't store your user's password as plain text or even encrypted; not in a session nor in the database. The passwords should be salted and hashed, see for example this question on SO.

You don't need the password in the session at all; after you have checked once for the correct credentials so there is no need to store it. If you protect yourself agains session hijacking, the information stored in the session (the username for example) is sufficient to validate the visitor.

Community
  • 1
  • 1
jeroen
  • 91,079
  • 21
  • 114
  • 132
  • So my AES Encryption does it wrong ? Even if I do `... WHERE uname=:u_name AND AES_DECRYPT(upass,:u_pass) = :u_pass;");`. Notice new AES_DECRYPT args. – David Apr 30 '14 at 21:57
  • 1
    @divad You should never encrypt a password, always use a salted hash (that is one way only). If the server can decrypt it, so can a hacker should something happen to your server. – jeroen Apr 30 '14 at 21:59
  • Hum.. You say servers should not be able to decrypt passwords. So how can I compare passwords in the future ? – David Apr 30 '14 at 22:10
  • 2
    You should use the specialized hash methods called bcrypt or scrypt instead of a basic salted sha hash. PHP 5.5 has these built-in. Older PHP versions can use the phpass library. – Martijn Heemels Apr 30 '14 at 22:10
  • 3
    @divad You don't. You generate a hash from the user-provided password on login and compare that to the hash in the database. See the question I linked to in the first paragraph and go for the "future practices" of the accepted answer. – jeroen Apr 30 '14 at 22:11
  • 1
    @MartijnHeemels Too much to add here, the question I linked to has it all :-) – jeroen Apr 30 '14 at 22:14
  • 2
    @divad Absolutely, but note that it is only available since php 5.5. For earlier versions (5.3.7+) you need the compatibility layer: https://github.com/ircmaxell/password_compat – jeroen Apr 30 '14 at 22:31
1

Session files are usually stored in /tmp which everyone on the server can read. So storing a password there is a bad idea.

/tmp is more important on shared servers rather than dedicated though

Storing a password anywhere is a bad idea. Always hash the password and then check the hash. Php has built in support since 5.5 And if you need it before then use a well known library such as phpass

exussum
  • 18,275
  • 8
  • 32
  • 65
  • Exactly. Any user that has access to read /tmp on the webserver could read session data. For hashing passwords always use a specialized password hashing method, such as bcrypt or scrypt, instead of a simple md5 or sha hash (even if you add a salt to those). Your suggestion to use the built-in function in PHP 5.5 (or the phpass library for older versions) is excellent. – Martijn Heemels Apr 30 '14 at 22:05
0

You are storing user's password in plain text format in $_SESSION directly from $_POST. You should avoid doing this, plain text password should not be stored anywhere.

After users credentials are verified against database you can set in $_SESSION that user is logged in, you don't need to check everytime if both user's password and username are stored in $_SESSION, something like this:

$_SESSION['logged_in'] = false;
if ($users_credentials_are_valid){
    $_SESSION['logged_in'] = true;
}

After that you can use in other files:

if ($_SESSION['logged_in']){
    // Content for logged in users only
}

I see that you use AES_DECRYPT, that's just wrong, because in that case you can reveal user's plain text password. Once password is in database, none should be able to access it in plain text format. You should always use some hashing algorithm, like this:

$pass = hash('sha256', $_POST['pass']);

It would be even better if you added salt to the password.