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.
Related
On the PHP website it is stated that "Developers must not use long life session IDs for auto-login because it increases the risk of stolen sessions.". Instead it is recommended to use a secure one time hash key as an auto-login key using setcookie() - which then becomes a persistent cookie.
But I cannot understand how that is safer?
The persistent cookie with the token can also be stolen and stealing sessions IDs is very difficult if you make sure your website never works with HTTP only, but only uses HTTPS - like with HSTS, and also prevent JavaScript access with httponly.
What am I missing here?
I have a guess what they mean. I believe when they say "secure one time hash key" they really mean some kind of HOTP mechanism. Then I have some more guesses what they want to achieve with it. They want to be able to terminate the sessions when they time out, but they also want the client to be able to automatically recreate the session by simply calling its internal HOTP mechanism and generating the next token and finally passing it to the server.
That's a huge amount of guessing here, but honestly, saying "secure one time hash key" does not mean a thing and such an expression is really vague.
I think I have found the correct answer myself.
A session cookie is used to keep state between requests. It can be used to track a login during an open browser session, but the session should be ended when the user logs out or when the browser is closed. A "Remember Me" token in a persistent cookie is not used to keep state between requests, it's only used to "skip" the login procedure and give access to specific pages that other wise requires a login. When you use $_SESSION you're dealing with the session cookie and nothing but the session ID is stored in the browser or client and all the values you put into the $_SESSION array gets stored on the server in a file (by default) that contains the values in pure text.
The persistent cookie for "Remember Me" is not used for anything like that, it only keeps a hash token in the browser in order for the user to be recognized and avoid having to log in every time he visits the website.
In other words, the session cookie and the persistent "Remember Me" cookie are two different solutions to two different problems.
You can "keep state" with the "Remember Me" cookie, but that is not what it is used for and it doesn't provide you with a session. You can use the session cookie to implement a "Remember Me" functionality, but that is not what it is used for, it is used to store state variables on the server and to keep state in a session.
However, if you implement the proper security features for cookies, i.e. only serve on HTTPS and use secure and httponly, then they are both equally secure with regard to the risk of stealing the cookie or the session ID.
I have several questions about SESSIONS and COOKIES, I read in internet and all people recommend use SESSIONS (for security) but.. Not is same save the ID login in one session (phpsessid) that save in one cookie?
I tested this:
I copied my PHPSESSID ID (cookie) from my login account from a website
( in chrome) and insert my PHPSESSID (cookie) in another browser (in
opera) with VPN and I can access in this account.
What is the security here? if anyone can guess or hijack my cookie PHPSESSID ID is same if I use a Cookie to saving the login id, or not?
My question is.. Dont is more secure use a secure cookie ID like in wordpress, encrypting ID and checking in DB the IP and USER_AGENT ?
Now, I using this:
I create a random ID and save in one cookie (when the user login is success)
And check if this ID exist in the DB, check if the IP (saved in DB) and USER_AGENT (saved in DB) is equal. if not, login another time
Anyone can me guide a little? Thx you for read.
You should ask yourself this: "How easy is it to guess the randomly generated random id?".
If your answer to this question is "very easy" you should make it harder to guess. Use a UUID or some other form of securely random ID.
If you answer is "quite hard" you should not have to worry about this. The only attack vector you are offering is to be able to guess a randomly generated id.
You can read more about "guessing the PHPSESSID" here.
In general it should not be necessary to check the IPs of the user (as a side note, you open up yourself to all the stuff in the GDPR by doing this) or their User-Agent as both things might change during the sessions lifetime.
The key point about sessions is that they are a server-side storage. In other words, your program writes whatever it sees fit and it reads back exactly what it wrote before because information cannot be tampered by clients as it happens with cookies. Additionally, the information remains hidden to client's eyes so it can store confidential or just internal uninteresting information. Last but not least, a PHP session allows to store most data types supported by PHP. A cookie can only store plain text.
The weak link in sessions is that HTTP is a stateless protocol so the client needs to identify itself on every request (unlike it happens in other network protocols as FTP, SSH or SMTP). Earlier implementations would transmit the session ID in the URL itself. It was later improved to only use cookies and cookies can be configured to be restricted to encrypted connections. But, yes, if something intercepts your HTTP traffic and finds out your session ID he can easily impersonate you because most sites don't care about implementing further checks. However, that's why HTTPS is encouraged nowadays.
I've made a website which has registration/login. I can see the PHPSESSID cookie in Chrome's Developer Tools, so I'm wondering how can I use this session id value to hijack into the account I'm logged, from let's say a different browser, for simplicity's sake?
Should a secure website be able to determine that this session is being hijacked and prevent it?
Also, how come other big sites that use PHP (e.g. Facebook) do not have PHPSESSID cookies? Do they give it a different name for obscurity, or do they just use a different mechanism altogether?
Lots of good questions, and good on you for asking them.
First.. a session is just a cookie. A 'session' is not something that's part of the HTTP stack. PHP just happens to provide some conveniences that make it easy to work with cookies, thus introducing sessions. PHP chooses PHPSESSID as a default name for the cookie, but you can choose any you want.. even in PHP you can change the session_name.
Everything an attacker has to do is grab that session cookie you're looking at, and use it in its own browser. The attacker can do this with automated scripts or for instance using firebug, you can just change the current cookie values.
So yes, if I have your id.. I can steal your session if you didn't do anything to prevent it.
However.. the hardest part for an attacker is to obtain the cookie in the first place. The attacker can't really do this, unless:
They have access to your computer
They somehow are able to snoop in on your network traffic.
The first part is hard to solve.. there are some tricks you can do to identify the computer that started the session (check if the user agent changed, check if the ip address changed), but non are waterproof or not so great solutions.
You can fix the second by ensuring that all your traffic is encrypted using HTTPS. There are very little reasons to not use HTTPS. If you have a 'logged in' area on your site, do use SSL!!
I hope this kind of answers your question.. A few other pointers I thought of right now:
Whenever a user logs in, give them a new session id
Whenever a user logs out, also give them a new session id!
Make sure that under no circumstances the browser can determine the value of the session cookie. If you don't recognize the cookie, regenerate a new one!
If you're on the same IP and using the same browser, all you have to do is duplicating the session ID (and maybe other cookie values: not really sure if browser specific things like its agent string is tracked/compared; this is implementation dependant).
In general, there are different ways to track users (in the end it's just user tracking). For example, you could use a cookie or some hidden value inside the web page. You could as well use a value in HTTP GET requests, a Flash cookie or some other method of authentication (or a combination of these).
In case of Facebook they use several cookie values, so I'd just assume they use one of these values (e.g. 'xs').
Overall, there's no real 100% secure way to do it (e.g. due to man-in-the-middle attacks), but overall, I'd do the following:
Upon logging in, store the user's IP address, his browser agent string and a unique token (edit due to comment above: you could as well skip he IP address; making the whole thing a bit less secure).
Client side store the user's unique id (e.g. user id) and that token (in a cookie or GET value).
As long as the data stored in first step matches, it's the same user. To log out, simply delete the token from the database.
Oh, and just to mention it: All these things aren't PHP specific. They can be done with any server side language (Perl, PHP, Ruby, C#, ...) or server in general.
Someone sniffs the session ID cookie and sets it for a subsequent request. If that's the only thing authenticated a user, they're logged in.
Most sites will use authentication based on cookies in some form. There are several ways to make this more secure such as storing info about the user's browser when they log in (e.g. user agent, IP address). If someone else naively tries to copy the cookie, it won't work. (Of course, there are ways around this too.) You'll also see session cookies being regenerated periodically to make sure they aren't valid for a particularly long time.
Check out Firesheep for a Firefox extension that performs session hijacking. I'm not suggesting you use it, but you may find the discussion on that page interesting.
Currently I autheticatic user sessions by matching a key in the session to the same key in a MySQl database. I regenerate the session with a random number that is MD5 protected on every page load. I am aware that sessions are not inherently secure and I'm looking for further security options that can be attached to this method in a speedy manner.
Any Ideas?
Since the session data is stored on the server side and the session ID is used to associate a client’s request with a certain session, it’s the session ID that needs to be protected. And the only viable measure to protect that session ID is to encrypt the connection between the client and server using TLS/SSL.
So you can use sessions as long as the data transfer between client and use is secured. Additionally, you can fix the PHP session to the TLS/SSL session so that the PHP session is only usable within that specific TLS/SSL session.
You're already jumping through hoops which do nothing to enhance the security, and potentially compromise the functionality of your site.
I autheticatic [sic] user sessions by matching a key in the session to the same key in a MySQl database
Even leaving aside the spelling mistakes, this is nonsense. Do you mean you authenticate requests by this method? If so, it's still not helping your security. You've already authenticated the request by de-referencing the session. Whether the request is authorized is completely different - if you need to authenticate the user then you should flag this in the session data.
It sounds like you're trying to prevent a CSRF, but getting this all mixed up with whether you're authenticating a user, a session or a request.
I regenerate the session...on every page load
Again, this is semantic nonsense. You can't "regenerate the session". Do you mean you create a new sessionId? If so then all you are achieving is creating errors when users try to open a second window or use the back button. It provides very little CSRF protection.
is MD5 protected
Just using random cryptographic functions doesn't make your application secure. It doesn't matter what the mapping between the real data and a surrogate identifier is, on its own it provides no protection against MITM.
Either you've done a very bad job describing your current security measures, or you've written lots of code which serves no useful purpose.
Go and read a lot of Stefan Esser's and/or Chriss Schiflet's stuff.
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.