Welcome Guest, Not a member yet? Register   Sign In
User ID, session data and security
#1

[eluser]Silviu[/eluser]
Hello,

I'm planing to build an application that (among other things) handles private data.
Every bit of private data has an "owner" field, to prevent users attempting to get/change other user's data. This is actually the user ID.

So, my plan is:
- User logs in.
- The ID is stored in a session variable.
- Every piece of data that is manipulated is checked against the stored ID, and only if it matches, the operation is permitted.

Using plain PHP, the user ID would have been stored in a $_SESSION variable. And this particular data would have been stored on the server only - and, AFAIK, it is not modifiable by the user in any way.

The CodeIgniter session class stores the "session" data in a cookie. And the cookie is stored in the user's computer - the information retrieved from the user should always treated as tainted.

My questions:

1: Since using CI sessions, the data is actually stored in the user's computer, how safe is to use the method outlined above? I mean, what are the chances of someone successfully decrypting/bypassing the encryption and change the cookie to access other user's data (this assumes that this person knows how the system works - but not the encryption key)

2: Ar there other methods to accomplish this? Something like storing for each session_id a corresponding user_id in the database, user_id that would be retrieved and used. But this will leave the door open to changing your session_id, so this is kinda back to square one, but without being able to change a specific user, since the malevolent user can't be sure about the user id he will get.

3: Another option - store not the user ID, but a custom hash (like sha1(md5(4userid)) and check against that? Or make the user_id not a simple number, but a hash in itself? sha1(md5(uniqid(true)))?

Well, any suggestions?
The privacy of the data is very important for me, and it's worth the time to implement a secure way to access it.

Thanks.
#2

[eluser]LuckyFella73[/eluser]
The short answer is: use DB sessions. That way you only get a cookie with
a session id, all other data is stored in your db. In an other thread I read
the hint to use a random encryption key that makes it even harder to manipulate.

For more informatios use the search function of this forums. There are plenty
of threads about Codeigniter session and security. Or wait for Wanwizzard who
has deep insight with sessions/ CI sessions.
#3

[eluser]pickupman[/eluser]
Welcome to the forums. As LuckyFella73 mentioned, using the [url="http://ellislab.com/codeigniter/user-guide/libraries/sessions.html"]DB[/url] will be more secure than a storing in a cookie. The only thing in a users session is the encrypted session id. The only downside is the small additional load that places on the DB. You can encrypt your cookie information as well. One thing I have seen implemented in some auth libraries is storing a random integer offset for a user id. Say a user id is 7 and a random integer is 13, you could save their user id in the session/cookie as 91 (7*13). That way no one could really know their user ID.
#4

[eluser]Silviu[/eluser]
Well, that's a good pointer to consider.

Adding a salt to the stored user id and encrypting the cookie data should prove a lot more difficult to crack.

Thanks.

Though I'm open to other ideas also :-)
#5

[eluser]LinkFox[/eluser]
I generally create a unique string for each user on registration and store this in the database along side the user ID. The user ID in this case is the AI id created by the DB on insert.

So a user has

user_id
unique_id
otherinfo

I use this for doing 'stuff' against a user, it would be pretty much impossible for them to guess the unique string of another user and combined with storing the session in the DB you're pretty much covered.

Regards

David
#6

[eluser]WanWizard[/eluser]
I do something similar. I also generate a unique salt for every user, instead of using the same salt to hash the password.

You could extend the session class and encrypt the userdata in the session record, using the session cookie as encryption key. That way you would need the correct cookie to access the data in the session. This will add some processing overhead, so only do this it it is absolutely needed.

Given the fact that you are in control of the application code, the things to worry about when it comes to securing data are:
- can access be obtained via the frontend? Thinks about sql injections, code injections, xss, etc
- can access be obtained via the backend? Another application accessing the database? Your administrators trustworthy? Physical security? etc.

For a secure application (including private and payment data) I recently designed for a client, no secure data was stored by the application. Instead, a highly secure system was designed that stored this info, which was only accessable via a secure web service. Only non-private data could be retrieved, for example a customer could change creditcard details, but never saw the orginal number stored, only for example the last four digits. This webservice was internal, not internet facing, and protected by a web service security firewall. Also things like payment requests where send to the backend by webservice, no processing in the frontend application.

It all boils down to: how secure do you want it to be, and what are you prepaired to spent to achieve it?
#7

[eluser]Silviu[/eluser]
First, the answers:
- No, there will be no way to obtain unauthorized access via the front end
- The sysadmin is a trustworthy person. There are other applications running on the server, but only this application will access it's database. Physical security is OK, AFAIK.

Second, some more details:
- The application is built into three main areas:
-- A small public area containing some minor advertisements for the application - like overview and key benefits, a register form, a contact page with a support ticketing system and maybe several other minor modules.
-- The private area of the app. This is what the user will see and act on.
-- A admin area

As an extra detail, the admin area will be (at least for the time being, since i want to concentrate on the users area) a one-user system. And that user will be me. And I think I'm pretty trustworthy :-)

I have started this thread because the information each user enters is private and pretty important, and I was worried about some malevolent user "highjacking" the session by altering the userid (if) stored on the user computer.

@WanWizard:
The solution you used for that recent application is WAY overkill and way too time consuming and costly to implement - I'm a one man team ATM.

As for how secure I want it to be, the answer is "secure enough that remote users will have no possibility of leaving their own 'userspace' and meddle with data that does not belong to them". That said, I plan that, short of hacking the server directly, the user has nothing else to do except what he was allowed to - manipulate his own information.
Again, I am confident that the server is physically secured. I'll ask the administrator to recheck the setup, although it's in his best interest to keep the server secure for his own reasons.

Some more details:
- The public area will have only minimal access to the database - public support tickets (like "i can't recover my password"), newsletter registration, and user registration requests.
-- I plan to keep the registration requests in a different table.
- The admin area will be hard locked to specified IP addresses
- Both the admin and user areas will be https only (Where can lone web developer get a low priced ssl certificate these days? :-) )

Once again, the user authentication will store a token in the session that will be used to identify the user for any other page requests/operations is does (at least that's the plan). So I was looking for a solution to secure this token / or not store it on the user's computer.
This token will be created only at login and later on the application will only request this token. It is not directly modifiable by the user or the administrator.

Thanks for all your answers.
#8

[eluser]WanWizard[/eluser]
Ok, so not THAT secure... :coolsmile:

If you're only concern is cookie hijacking, know that CI tries to mitigate that by adding the user's IP and User Agent string in the cookie, together with the session ID and a timestamp.
The cookie payload then gets encrypted (make sure you set a good and random encryption key in your session config!).
Also, CI by default rotates the session ID every 5 minutes.

So, you can hijack a session if:
- your PC has the same IP address are the one you stole the cookie from (or you're able to fake that)
- you use exactly the same browser (or you know the exact user agent string and fake it)
- use it to attack within the session ID rotation time left
or if you can crack the encryption, guess someone elses session id, and construct your own cookie.

In short, a lot safer than some other session inplementations, including PHP's own session management.

As for cheap certificates, see http://www.whichssl.com/comparisons/price.html

p.s. and you can trust the other applications? Because if one of those gets hacked, they can use it to access your database config, find the database name, userid and password, and login to your database. Only needs a few lines of PHP...
#9

[eluser]Silviu[/eluser]
To be honest, I'm not sure ATM about the other applications regarding trust level. I've added this to my checklist :-)

And, to be more precise, my concern is not cookie highjacking per se, my concern is that a user that received a legit cookie, can modify that cookie and change the id/token stored in it to identify itself as another user.
Having everything compared to the stored user's id, I view this aspect as an Achilles' heel, so I'm collecting data on this matter to see if CI sessions are secure enough for this purpose.


So far, I have identified several details that I should have in my setup regarding this matter:
- Alpha-numerical user ID/token (a alpha-numerical GUID)
- Encrypt the session data with a strong encryption key
- Store the session data in the database
- Have the stored user ID/token processed through a hash function before storing it

Do I have to take anything more into account? Or am I being too paranoid? :-)


Another thing... having the session data stored in the database means that only the session ID is stored on the user computer?
If true, then:
- This means I don't have to worry about exposing the user ID, since it does not leave the server (hence I don't have to hash it or use a alpha-numerical values as mentioned above).
- If the user can change the session id, then, according to the above setup, can he get access in the system as another user (asuming that he is lucky enough to get a valid session ID)? From what I understood until now it cannot, but I'm asking again to be sure.
- How secure is the session ID stored in the user's computer?
--- How long is it? The database field is a varchar(40).
--- I suppose it is encrypted if the encryption is enabled.
--- Can the session id rotation time be decreased? Is it worth it?

Thanks.
#10

[eluser]WanWizard[/eluser]
The payload of the session cookie contains:
- session ID (an MD5 hash)
- client's IP address
- client's Browser User Agent string
- last session ID rotate timestamp

This is an array, which is serialized and then encrypted using the encryption key in your config. The security of this key is the most important thing, it determines how secure your cookie is.

As to the user hash, generate a new one every time the user logs in, and store it in the user record. That way an old cookie can't be used. Side effect is that a user can be logged in only once though.

As for rotation times, you can make it as short as you want. Note that you'll have to think about garbage collection, every rotation means a new session record, you may want to prune your session table more often. Also note that CI's session class is not Ajax proof. If your site uses Ajax calls, you have to disable session id rotation on ajax calls losing the session.




Theme © iAndrew 2016 - Forum software by © MyBB