Since every user has a unique PHPSESSID, is it possible for two users, say a to inject info into b's SESSION data using standard PHP running on the server.
Note, I am not using this for any wrong purposes. Trying to use it for chatting without DB access.
Thank you for your time.
I'm assuming you want to somehow have A chat to B by sending a message which gets placed into B's session.
First of all, A needs to learn B's session ID, perhaps by selecting their name from a list. You'll almost certainly want to encrypt these session ids, otherwise you have created a nice security hole!
So, A posts data to the server containing the target session id, and a message. Here's how we could temporary switch session ids to write that data into the target session:
//get data from form - I'll leave the encryption of the target
//session id up to you!
$target_session_id=decryptSessionId($_POST['target']);
$message=strip_tags($_POST['message']);
//remember our "real" session id and close the session
$original_session_id=session_id();
session_write_close();
//open the target session
session_id($target_session_id);
session_start();
//add message to target session
$_SESSION['chat'][]=$message;
//close target session
session_write_close();
//reopen the "real" session
session_id($original_session_id);
session_start();
Read up on session fixation
Session is a simple thing that can be easily reimplemented to do as you wish. Take a look at this simple exemple I wrote some time ago: http://pastebin.com/f3ca0ae8d
Usage:
new mySession(); doing the same as session_start();
$_MYSESSION doing the same as $_SESSION
delete mySession(); doing the same as session_write_close(); not necessary to use unless you want to release the session before the script end.
You can make some adaptations to use it in your specific purpose, like defining the session ID yourself so you can share it among different users. As $_MYSESSION will be common among users, you can also use regular PHP Sessions together with it to store user specific information in $_SESSION.
[Edit]
http://pastebin.com/f3c31737e
Exemple: Enter the channel $_SESSION['channelid'] and print all unread lines.
session_start();
new mySession($_SESSION['channelid']);
while (count($_MYSESSION['chat']) > 100) unset($_MYSESSION['chat'][key($_MYSESSION['chat'])]);
while ($line = $_MYSESSION['chat'][$_SESSION['lastread']++])
echo "$line";
Exemple: Talk to the channel.
session_start();
new mySession($_SESSION['channelid']);
$_MYSESSION['chat'][] = $_SESSION['myname'] . ' says, "' . htmlspecialchars($_POST['message']) . '"';
etc...
Instead of farting around with what is, essentially, indirect file handling through the session system, why not go straight to the point and use text files?
It's less vulnerable to attacks, and also less volatile, in the sense that future versions of PHP could decide to prevent this sort of session switching for security reasons (complete hypothetical, but it makes sense).
I can't say for sure but since session data is by default stored in a file, if your app knows the session id of the other user you could replace in the session file that was written by the standard session functions with altered data. The next time the other user accesses a script the altered session data will be loaded.
But you are risking all sorts of race conditions and conflicts if you just do this on top of the built in session handling. You will probably want to replace the session handling functions with your own so you can deal with all of these issues. The issues are probably much more complex than they appear on the surface.
See: http://www.php.net/manual/en/session.customhandler.php for information about custom session handlers
PHP’s default session handler uses only the session ID to identify the session. That makes it possible to use the session ID from another user and thus use the same session (Session Hijacking). Another attack is to prepare a session and get the victim to use that session so that the victim and attacker again use the same session (Session fixation).
The base for such attacks is that you just need to know the session ID to use the session that is associated to it. Prevention techniques are to use more identification information than just the session ID. Some suggest to use the IP address (but that may change during a session) or the user agent identifier. Another technique is to hide the session ID externally by allowing only a cookie and HTTPS.
But be also aware of shared hosting. Some might use a common pool for all session data files of all cumstomers.
Related
So I recently made the decision to use Session ID's for authentication on my website instead of JWT's, so I'm still trying to play catch up a little bit here.
I guess my concern is pretty simple. If I'm going to have my database handle my sessions that are currently active for the users that are logged in (probably through a table that has a column with the UserID and the SessionID) how can I use PHP to generate a completely random Session ID? I will then pass that Session ID into a httpOnly cookie.
I assume this will work with my Angular front-end as I can use the withCredentials boolean option on every http request since I won't have direct access to the Session ID cookie.
So when a user wants to access a restricted area, their http request will contain the Session ID cookie and my PHP will determine what their User ID is by doing a lookup on the CurrentSession table. This will then allow PHP to determine the user's access level.
All this will be done over a HTTPS connection but I think I will still have to worry about CSRF attacks so I will probably use the Double Submit Cookie method as Angular already provides support for it.
So I guess my main question is, would simply finding out a way to generate a unique Session ID with PHP work for securing my app? Or would somehow encrypting the Session ID so only my PHP can decrypt it be a good idea, so in case somehow an attacker got access to the Session ID from the cookie, it would solely be an encrypted version of it, so it would be useless.
I would suggest using PHP's session_start() which will handle the session in its entirety including any cookies that need to be written to maintain the session depending on your particular connection at the time.
All you need to do is put this at the very top of your PHP scripts:
<?php
session_start();
A PHP constant "SID" should be available to get your session id which you could store in MySQL for other purposes if you wanted to - but it may not be necessary. You can also use session_id() as well.
I am a little confused on storing sessions with regards to having multiple users logged in at the same time...Does the session key have to be unique or just the value? Like is this ok, if all the $userIds are unique?
//if the user logs in:
$_SESSION['loggedIn'] = $userId;
In testing this it seems like if you have two logged in with separate $userIds at the same time and are trying to enter data to a db, it causes errors. Should the key be a random #? Not worried about security at this point.
The $_SESSION vector is part of the [Session management] of PHP:
Session support in PHP consists of a way to preserve certain data across subsequent accesses
It basically let's you store information in a per session fashion, and retrieve that same information in a subsequent call from the same session.
Each session have it's own data set.
PHP uses a cookie or a POST/GET parameter to identify each session and thus determine if the current call is part of a existing session and provide you with the data you stored there in previous calls.
session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.
For more info, take a look at this topics in the manual:
session_start()
session_name()
session runtime configuration
$_SESSION is stored on the server side and is not a good way to track a user as a session can be terminated after a short period of inactivity. You'd be better off using cookies, if possible.
But to address your specific question, your code should work as the session will almost always be unique.
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.
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.
What's the best and most secure way to go when writing an authentication library in a model-view-controller way?
The things that give me a hard time are keeping track of the users activity and remembering users via a cookie or storing sessions in the database?
Thanks in advance :).
If you want to use sessions, you have secure them against attacks like session fixation and session hijacking.
To prevent both you have to ensure that only authenticated requests are allowed to use the session. This is commonly done by chaining as many specific (possibly unique) informations about the client as possible with the session. But as some informations may change on every request (like the IP address), it can be difficult to find good one.
This is why it is useful to use the method denoted as Trending.
Another good protection measure is to swap the session ID periodically. Thus the period for an attack on a valid session ID is smaller.
The simplest way to implement it is with PHP SESSIONS.
just session_start (); near the beginning of your script and you have access to the $_SESSION global array for holding your authentication data.
Depending on the configuration of your server all the data stored in $_SESSION will only be available on the server from which it is hosted (with few exceptions). You can configure it to be saved in a temporary directory, in memcached, or even a database.
The only thing that is transmitted between the client and your server is a "session key". The key can be passed by cookie or URL-rewrites (which are transparently handled by the start_session output buffer).