Let's start with the good news: The $_SESSION
array is by default completly invisible and inmanipulable by the client: It exists on the server, and on the server only, in an execution environment, that is not open to the client.
Now back to earth: It is quite easy, to get your PHP code "nearly right" and thus open a door between the client and the session as seen by the server. In addition to this, stealing a client session (including a cookie) is quite easy.
I recommend a few mitigations, that have been proven quite effective:
- Do not store a "logged in" value - instead store a "session cookie" value, and set the cookie to the client. On a client request make something along the lines of
$loggedin=($_SESSION['cookie']==$_COOKIE['session'])
. This makes the attacker need both: cookie and session ID. - Refresh the session cookie quite often, on a wrong cookie kill the session. If a black hat steals cookie and session, the next click by the real user will log out both and create a logable event.
- If your requests come from JS, think of creating a simple authentication function: Instead of sending the authentication token, salt it, pepper it with a timestamp, then hash it. Send salt, timestamp and hash. Make the server check the timestamp.