Jump to content

Question about authentication


Strahan
Go to solution Solved by requinix,

Recommended Posts

Hi.  Question for you all.  The way I authenticate now, I check if a session var "authUID" exists.  If not, I present the auth form.  If they log in correctly, I set $_SESSION["authUID"] = $dbrecordsetvar["uid"];

 

Is that secure?  Session vars are not exposed to the client at all, correct?  Just wanted to verify.  Also, would it be better to store the password they entered on the form (encrypted) instead of the db's UID for their account then just check it against the DB every time I load sensitive pages?  I figured that may be better as it would catch if the pwd changed on another client and boot them but I wasn't sure if I'm being over paranoid and wasting resources on a SQL round trip every time or not.  It's a low traffic application though, so I think the resource hit would be negligible. 

 

Thanks!

Edited by Strahan
Link to comment
Share on other sites

  • Solution

Unless you have a weird PHP configuration that's possible but one I've never actually seen anyone do (because it's so stupid) then data in $_SESSION is safe. But remember that sessions use cookies, so if a bad person gets a hold of a good person's session cookie then they could hijack their session. There's a lot written on the subject of session hijacking, but that's besides the point.

Also consider that people using shared hosting are sharing the same machine with other hosting accounts, and since sessions are normally stored as files, it's possible (again, depends on the server configuration) for one of those other accounts to look at session data.

 

Since it's safe, storing only the ID is fine. Storing the password is flat-out bad, regardless of hashing or encryption, and that applies to dedicated hosting as well.

 

Speaking of, passwords should be hashed. Not encrypted. Hashing can't be reversed but encryption can be. Use PHP's password_hash/_verify functions for that.

 

When a user wants to change their password, you should prompt them to enter their current one anyways - either through a secondary login screen (eg, "confirm your account") or through a confirmation box in the form. You should then change their session ID via session_regenerate_id(), which is actually something you should do on a regular basis anyways but is a bit more complicated than just that.

 

As for catching the password change, that's a question for you. Do you want to boot a secondary session because the password changed on another one? I probably wouldn't. You can always give the user a sort of "log out all other devices"-type action; if that was in place then you would have to check the DB on every page load anyways.

Link to comment
Share on other sites

If you want help with security, you have to be a lot more specific. The current description sounds more like a bunch of random ideas than a concrete problem.

 

So you're storing the user ID in the session (which is pretty much unavoidable), and you're worried about ... what exactly? The user ID is public, so confidentiality isn't an issue. Do you think somebody might replace the user ID in their own session with the ID of somebody else?

Link to comment
Share on other sites

Unless you have a weird PHP configuration that's possible but one I've never actually seen anyone do (because it's so stupid) then data in $_SESSION is safe. But remember that sessions use cookies, so if a bad person gets a hold of a good person's session cookie then they could hijack their session. There's a lot written on the subject of session hijacking, but that's besides the point.

Also consider that people using shared hosting are sharing the same machine with other hosting accounts, and since sessions are normally stored as files, it's possible (again, depends on the server configuration) for one of those other accounts to look at session data.

 

Since it's safe, storing only the ID is fine. Storing the password is flat-out bad, regardless of hashing or encryption, and that applies to dedicated hosting as well.

 

Speaking of, passwords should be hashed. Not encrypted. Hashing can't be reversed but encryption can be. Use PHP's password_hash/_verify functions for that.

 

When a user wants to change their password, you should prompt them to enter their current one anyways - either through a secondary login screen (eg, "confirm your account") or through a confirmation box in the form. You should then change their session ID via session_regenerate_id(), which is actually something you should do on a regular basis anyways but is a bit more complicated than just that.

 

As for catching the password change, that's a question for you. Do you want to boot a secondary session because the password changed on another one? I probably wouldn't. You can always give the user a sort of "log out all other devices"-type action; if that was in place then you would have to check the DB on every page load anyways.

 

Sounds good, thanks a lot.

 

 

If you want help with security, you have to be a lot more specific. The current description sounds more like a bunch of random ideas than a concrete problem.

 

So you're storing the user ID in the session (which is pretty much unavoidable), and you're worried about ... what exactly? The user ID is public, so confidentiality isn't an issue. Do you think somebody might replace the user ID in their own session with the ID of somebody else?

 

Well, yea, it basically is a bunch of ideas at the end there because I wasn't sure the best way to approach it.  I explained what I am doing now in the first few sentences (storing IDs).  When I say ID, I don't mean like "Jacques1" I mean the index value in the database.  Nobody sees that.  I just wasn't sure if that was a good approach or not.

Link to comment
Share on other sites

When I say ID, I don't mean like "Jacques1" I mean the index value in the database.  Nobody sees that.

 

Users will see their own ID and most probably the IDs of other users. For example, in the database of this forum, yours is 69813.

 

 

 

[...] I wasn't sure the best way to approach it.

 

Best approach to what?

 

You haven't even defined the problem, so I'm surprised that you now claim you've found the solution. The description of a vulnerability typically looks like this: “If x manages to do y, then z happens”. In your case, who does what, and what are the consequences?

 

Users can in fact see the internal database IDs. Why do you think this is a problem? You do have a problem if users can change the ID in the session (e. g. due to a session poisoning vulnerability).

Link to comment
Share on other sites

Users will see their own ID and most probably the IDs of other users. For example, in the database of this forum, yours is 69813.

 

I find it hard to believe you can put forth such a gross generalization.  Just because IPBoard exposes a user's db ID doesn't mean every other PHP site in existence does.  

 

You haven't even defined the problem, so I'm surprised that you now claim you've found the solution.

 

My problem (which I defined in my first post) was just that I wasn't sure if it was secure/acceptable to store a piece of data in a session variable to track whether or not a user was logged in, or if I should find some other method.  requinix said "Unless you have a weird PHP configuration that's possible but one I've never actually seen anyone do (because it's so stupid) then data in $_SESSION is safe" which answers that question, ergo my closing this out having found my answer.

Edited by Strahan
Link to comment
Share on other sites

I find it hard to believe you can put forth such a gross generalization.  Just because IPBoard exposes a user's db ID doesn't mean every other PHP site in existence does.

I can't think of a single site, PHP or not, that has users and does not expose the user ID in some way.

 

Picking basically the first link I can find on these sites:

- StackOverflow: "Rana Ghosh" is #6162401

- MSDN Forums: "Imtiyazk" is 370588b4-fbbe-45a5-b066-bfb0fa31debf (that's a GUID)

- Slashdot: "Aethedor" (first comment) is #973725

- Wikipedia: "Segehelmus" is #21621158

- Twitter: Rachel Maddow is #59437078

- Facebook: MrBean is #17774451468

 

Or maybe you would like to pick a site for me to check?

 

The ID number (or GUID) is irrelevant. It doesn't matter if anyone knows it.

Link to comment
Share on other sites

I find it hard to believe you can put forth such a gross generalization.  Just because IPBoard exposes a user's db ID doesn't mean every other PHP site in existence does.

 

His point is that (if the application is properly built) exposing the ID should not pose a security threat. If so, the application should be fixed rather than relying upon obfuscation as security.

  • Like 1
Link to comment
Share on other sites

Just because IPBoard exposes a user's db ID doesn't mean every other PHP site in existence does.

 

You couldn't hide the IDs even if you wanted to. And until now, you haven't even managed to come up with a reason for why you want to hide them.

 

 

 

My problem (which I defined in my first post) was just that I wasn't sure if it was secure/acceptable to store a piece of data in a session variable to track whether or not a user was logged in, or if I should find some other method.

 

You haven't defined anything. As you already said, you're just throwing random ideas around. If you want an actual security assessment, we need hard facts.

 

But if you don't think your problems are important, I'm fine with that. Sleep well.

Link to comment
Share on other sites

The problem I was having and wasn't sure about was whether or not it's safe to store their ID in a session variable and use that to determine if they are logged in, and logged in as whom.  As I said in the first post, I just check if a session var is set and if not they get the login prompt and if so the system uses the id in the var when it needs to check if the person has rights to do something.  I wasn't sure if session variables were exposed to the client, where they could change their ID in the session var and become someone else.  

 

I also see, looking at the examples, that yea I was way off base in regards to my exposed IDs on sites notion.  I can't find a site user interaction that doesn't have them visible, as you guys said lol.  My bad :)

Link to comment
Share on other sites

I wasn't sure if session variables were exposed to the client, where they could change their ID in the session var and become someone else. 

 

Now we're getting somewhere. I actually asked you if that's what you're worried about in my very first post. ;)

 

And now it's possible to give you a more nuanced answer: Yes, there are cases where the user ID in the session can be manipulated, even if the session data isn't directly exposed. Possible causes are a session poisoning vulnerability or a session directory which is shared among multiple applications or a vulnerability which gives the attacker write access to the session files. All of this happens and must be actively prevented.

 

The ideal solution would be to make the user ID read-only. Unfortunately, that's not really possible with standard file-based sessions. An alternative is to calculate a message authentication code over critical data like the user ID, so that changes require knowledge of a secret key (i. e. simple manipulations are no longer possible). And of course you should systematically prevent the vulnerabilities I mentioned above:

  • Use a separate session directory for each application.
  • If your PHP environment uses the modern PHP-FPM API, consider setting up a separate pool with a separate Unix account for the application. This makes it a lot easier to prevent external file manipulations.
  • Be very careful whenever you're writing data to the $_SESSION array. Make sure the array index cannot be influenced by the user.

 

 

 

I can't find a site user interaction that doesn't have them [the user IDs] visible, as you guys said lol.

 

Sure, because really the whole point of the IDs is to act as (public) references within URLs etc.

 

All you could do is have two IDs: a public ID which is exposed on the website frontend, and a long random internal ID which is only used on the backend. However, this is complicated and not very effective compared to the above suggestions.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.