What to store in a session? - php

I know about all the issues with session fixation and hijacking. My question is really basic: I want to create an authentication system with PHP. For that, after the login, I would just store the user id in the session.
But: I've seen some people do weird things like generating a GUID for each user and session and storing that instead of just the user id in the session. Why?
The content of a session cannot be obtained by a client - or can it?

You're correct. The client just sees a randomly generated session id token. There are ways this token can be misused (hijacked, etc.), but having a GUID on top adds nothing. In contrast, options like session.cookie_httponly (JavaScript can't see session cookie) session.cookie_secure (Cookie can only be transmitted over HTTPS) protect against certain attack scenarios.

The short answer is that $_SESSION is safe and you do not need to worry about its contents being leaked to a user or attacker.
The content of the session is not normally be accessible to the user. You should be able to store the user's primary key and you'll be fine. There are cases where the session can be leaked, on a normal linux system the session folder is in /tmp, however this could be changed in your php.ini to the web root (/var/www/tmp) and then could be accessible. The only other way is if the user is able to get access to the $_SESSION super global by hijacking a call to eval() or by the variable being printed normally.
If you are running on a shared host and using an old version of PHP and/or your server is misconfigured it might be possible for another user on this system to read or even modify a session file stored in /tmp/. I don't know of a single application that takes this attack into consideration. If this is a problem you can store the information in a session table in the database.

Sometimes, for added security, developers may assign a long string to the user's session in order to make hijacking even more difficult. By setting a cookie with this new string at the time of session creation, the app can check for the correct string on subsequent requests to better ensure it is the person who actually logged in.
It's just adding one more thing a wannabe hijacker would have to guess. However, it can be a false sense of security as it does little to protect the session if sniffing is involved because the new cookie is sent right along with the php session cookie. Also, session id's are very hard to guess as it is (as I'm sure you know, just don't place it in the url but, rather, in the cookie).
Session info is stored on the harddrive so it's not obtainable by clients without application intervention.

I've never seen GUIDs being used for sessions, but there are a couple of additional methods I have seen that do add a little more security.
Storing the user's IP - if you need to force a session change based on locations (sometimes geoIP stuff will do this)
Storing the user's HTTP_USER_AGENT header string. Can provide a bit of security against hijacking if the hijacker happens to be using a different browser.
There's a great article on session hijacking countermeasures on Wikipedia, actually.
That being said, I would imagine that anyone storing a GUID as part of a session to use in session security might be failing to see a better solution (such as session regeneration). I can see other uses for a GUID to be stored (maybe it's part of a random generator for a game), but not for use with session security.

Related

how to prevent sessions id from being seen in debuggers?

So it seems like Opera Dragonfly is able to cache cookies as well as session info. In particular the PHPSSID my question is. Would there be a way to hide PHPSSID from being shown by any time of debugger/developer tool?
I don't mind cookies since they are secured. As the data in them is hashed with double salt as well as few other things so forging them is no a problem for me.
But I want to assure PHP sessions are not seen. How would I be able to achieve this?
In short the answer is: You can't, that is not session id's work.
The point of a session id is that is a very random number, often called a cryptographic nonce. This value is intended to be very difficult to guess, it is then used to reference state about that session on the server side. This could be in a database or by default PHP uses the file /tmp/THE_SESSION_ID. The data stored in $_SESSION is stored in this file and the user cannot obtain this data.
In PHP to keep attackers from stealing a user's session id you should set session.cookie_secure=On in your php.ini. This forces the session to be over HTTPS.
If you are using HTTPS, then the session id will be obscured from attackers on that network. By using HTTPS session id's cannot be hijacked with tools like Wireshark or Firesheep. Not using HTTPS is a violation of OWASP A9: Insufficient Transport Layer Protection. However a user can still see his own session id by looking at his cookies javascript:document.cookie or by using TamperData.

PHP user sessions

I'm bit confused. I've been building my sites with my own session system, but i'm not sure how secure the php's own session system is. My session system usually just has user id and quite harsh hash, which does not include user name or password for generation. I save the hash in the user database and as a cookie to confirm the user session on every page load. So my question is can i trust php sessions or keep using my own?
PHP saves a unique session id in a cookie, and all values related to the session in it's own text file on the server. You have to get the session id to steal the session, which means you have to steal the session cookie from the victim's computer. PHP's own system is at least as safe as your homebuilt system
The difference may be how hard it is to find an active session by brute force. That is entirely up to the hashing algorithm and the random number generator.
You can configure PHP to use different hashing algorithms or you could even use your own algorithm to create the session ids for PHP's session system if you don't trust PHP to do it properly.
Storing data in cookies versus using PHP's sessions is very different. Cookies store data on the client-side; sessions store data server-side, which has a number of benefits:
The user can't see it
The user can't modify it
The browser doesn't need to send the data to the server with every request
Normally PHP sessions do store the session key as a cookie (although they don't have to), but none of the data you actually care about is ever sent to the user, it's stored on the server and looked up using the session key
i'm not sure how secure the php's own session system is
And the rest of the world is not sure how secure your's is. A lot of people have looked at the session handler in PHP and not found any flaws in implementation. Its also well characterizied and integrated but supports the notion of user defined handlers.
I'd recommend using the standard session code - but you might want to write your own handler functions.
C.

Cookies/Sessions login system

When a user logins I get him/her's ID and save it in a session var. What I wonder is, is this the way to go? Or should I use cookies? so it automatically login and so on.
session_start();
ifcorrectlogin {
$_SESSION['id'] = mysql_result($loginQuery, 0, 'user_id');
}
how do you authenticate your users?
//Newbie
Yes, this is the way to go. The session itself is already backed by a cookie to remove you any programming efforts around that. The session (actually, the cookie) will live as long as the user has the browser instance open or until the session times out at the server side because the user didn't visit the site for a certain time (usually around 30 minutes).
On login, just put the obtained User in the $_SESSION. On every request on the restricted pages you just check if the logged-in User is available in the $_SESSION and handle the request accordingly, i.e. continue with it or redirect to a login or error page. On logout, just remove the User from the $_SESSION.
If you want to add a Remember me on this computer option, then you'll need to add another cookie yourself which lives longer than the session. You only need to ensure that you generate a long, unique and hard-to-guess value for the cookie, otherwise it's too easy to hack. Look how PHP did it by checking the cookie with the name phpsessionid in your webbrowser.
Cookies can be manipulated very easily. Manage login/logout with Sessions. If you want, you can store the users emailaddress/username in a cookie, and fill the username box for them the next time they visit after the present session has expired.
I would try to find a session engine so you don't have to deal with the misc. security issues that bite you in the ass if you do the slightest thing wrong. I use django which has a session engine built in. I'm not aware of the other offerings in the field although I would assume most frameworks would have one.
The way they did it in django was by placing a cryptographic hash in the user's cookies that gets updated every page view and saving all other session information in a database on your server to prevent user tampering and security issues.
As BalusC mentions, the session_-functions in php are the way to go, your basic idea is sound. But there are still many different realisations, some of them have their pitfalls.
For example, as Jonathan Samson explains, using cookies can result in security holes.
My PHP is a bit rusty, but I remember that the session_-functions can also use session IDs that are encoded in URLs. (There was also an option to have this automatically added to all local links (as GET) and form targets (as POST). But that was not without risks, either.) One way to prevent session hijacking by copying the SID is to remember the IP address and compare it for any request that comes with a valid session ID to to IP that sent this request.
As you can see, the underlying method is only the start, there are many more things to consider. The recommendation by SapphireSun is therefore something to be considered: By using a well tested library, you can gain a good level of security, without using valuable development time for developing your own session system. I would recommend this approach for any system that you want to deploy in the real world.
OTOH, if you want to learn about PHP sessions and security issues, you should definitely do it yourself, if only to understand how not to do it ;-)

Session variables can be fooled (login)?

IN PHP:
Is there a way for the user to fake a session variable?
Is it secure to trust in the value of a session variable for a login system?
The session data is stored on the server. Only the session id is transferred forth and back between the client and the server. Unless a server-side script messes up (or there is a bug) the client cannot change the session data directly. But you have to ensure that only the "correct" client knows the session id, as it ties this particular client to a particular session. E.g. (since you mentioned a login) use session_regenerate_id() whenever a login (attempt) is performed to prevent session fixation
Sessions are stored on your server, either in a file or in memory. The user only holds a cookie that defines the path (usually a hash of some form) to the session data on your server. Theoretically you could change the cookie to someone else's hash, but that is very, very improbable, unless you store them as files and don't delete them after they expire, in which case the probability of someone exploiting an old session would increase.
Yes.. It's called session forge/hijack.
You change the value of the session cookie until you get another user session.
To avoid storing session data in the server, you can sign the content you want to protect from change, before storing it on session, and then validate just after retrieval from session. In PHP this process is reasonable simple and eliminates server storage issues.
Notice that this does not protect session data from being visualized. If you need this protection, you can still avoid server storage by using safe encryption. Just beware that virtually every encryption scheme based on key size can be broken on near future. So if you need to protect your session data for say, 5 years, the secure choice of key and algorithm might create performance issues.

a few questions regarding php sessions

ive heard a few timse that sessions need to be cleaned with mysql_real_escape_string or htmlspecial chars because they can be modified. what im wondering is how are they modified because when i look at a websites session named PHPSESSID the value it contains is always encrypted.
first of all what encryption method is it using and how is it modified. the reason i want to know this is to better understand how to secure myself based on what methods people are using out there to high-jack sessions
thanks.
They cannot be modified, they're stored on the server. The PHPSESSID is just an identifier, it's not encrypted but randomly generated (so it's unique to each user). People hijack sessions by stealing the PHPSESSID cookie, usually through a cross site scripting attack. Read the answer to this for a nice summary of sessions in php - What do i need to store in the php session when user logged in
Sessions are stored on the server. That means all data is stored in temporary files and are deleted after an x amount of time. The browser does not store session data. It stores an ID of the session, which the server uses to get the right temporary file.
So the user never actually has access to variables stored in a session. But has a reference to their session. It is possible to get someone else's session ID. This way you can pretend to be another user. If sessions are used for validation.
Read up on session hijacking here.
The thing that can get modified is the session id send to you by the client. So, as with all user supplied data, this needs to be 'cleaned' before you use it anywhere, like for example with mysql_real_escape_string before inserting it into a MySQL database.

Categories