How secure are PHP sessions?

2019-03-08 11:09发布

问题:

I'm primarily a C++ programmer, but I'm trying to pick up some PHP.

Apparently the way to implement web user sessions is to store the user's login ID in a cookie using the $_SESSION variable.

Is it not possible for someone to just modify their cookie, to give them different privileges or log in as a different user?

It seems like this authentication mechanism is just having the user store their ID in a file - and then just trusting them not to change it.

Is there something that prevents this?

Thanks!

回答1:

No, a session is stored on the server and cannot be accessed by the user. It is used to store information across the site such as login sessions.

Here is an example of the usage:

<?php
session_start();
if (password_verify($_POST['password'], $hash)) {
    $_SESSION['auth'] = true;
}
?>

The session can then be accessed across the site to check to see if the user has been authenticated.

<?php
session_start();
if ($_SESSION['auth']) {
    echo "You are logged in!";
}
?>

The user cannot edit these values however the session's ID is stored on a computer through a cookie as a long random string. If an unauthorized user gains access to these strings it is possible for them to access the site.



回答2:

PHP sessions are only secure as your application makes them. PHP sessions will give the user a pseudorandom string ("session ID") for them to identify themselves with, but if that string is intercepted by an attacker, the attacker can pretend to be that user.

What to do

This information is taken from "Session Management Basics" in the PHP manual, but simplified a bit. Some things may have been missed. Be sure to read through that as well.

  1. Always use HTTPS

    • Prevents attackers from reading the session ID cookie
  2. Enable session.use_strict_mode:

    • Rejects uninitialized session IDs
    • Ensures any sessions created are actually valid, so you can trust a prefix (eg, if the prefix is $userId-)
  3. Enable sessions.use_only_cookies and disable session.use_trans_sid

    • Avoids user sharing session ID accidentally by sharing a URL with the session ID in it
    • Prevents the session ID from appearing in a Referer header
  4. Periodically regenerate the session ID and invalidate old session IDs shortly after regenerating

    • If an attacker uses another user's session ID, regenerating will invalidate either the user's or attacker's session, depending on which makes the request that regenerates the ID. You can then track when someone tries to use a session that has been regenerated already, and invalidate the regenerated session at that point. The user will be able to log in, but the attacker (hopefully) won't be able to.
  5. Optionally keep track of additional information in $_SESSION that relates to the request (IP address, user agent string, etc)

    • If an attacker somehow gains access to a session ID, this can possibly detect the intrusion before the attacker can access any data. However, keep in mind that this may worsen the user experience. For example, the IP address may change when the user switches from a mobile network to Wi-Fi, and the user agent string may change when their browser automatically updates. Adjust the data checked according to the tradeoffs your site is willing to deal with.


回答3:

Answering this question needs 2 approaches:

  1. PHP session IDs are hard enough to guess for most use cases. Not much harder or less hard than other widely used systems.

  2. Trusting only a session cookie (and only the existance of a session cookie) seems not to go very far security-wise to me, no matter where this session cookie comes from - PHP or elsewhere.

So, in short: PHP sessions are as secure, as your use of them makes them be. This is true for any session-cookie-based system I know of.



回答4:

If do this:

$_SESSION['user'] = $username;

Then $username will not be directly stored in a cookie. Instead a unique session id will be generated and stored inside a cookie.

The info that you store in $_SESSION is only stored server side and never sent to the client. On subsequent request by the client, the server will load the session data by the id stored in the cookie when you do session_start().

It relatively secure. The only thing that can happen is that somebody could intercept the session id and thus steal the real users session. HTTPS can prevent that from happening though.



回答5:

Whatever answer you get on this topic you are most likely not going to be satisfied because there are so many different opinions on the topic. There are even entire books written about sessions and PHP security in general.

The best answer you can hope to get here is probably "sessions are as safe as you want them to be". More work and a larger number of precautions will obviously make them safer to use but the implementation itself will consume more time. As with everything you are the one to measure how much safe is safe enough for your needs.



回答6:

Since you are a C++ programmer, you only need to know that the session visible to the client side is just a pointer on a different address space (the server) and, therefore, the session cannot be accessed from the client mode.