Viewed   59 times

I need to use the password often in a session. I'm crypting my userdata with a key that is crypted by the password. So there is my question. Is it secure to store plaintext passwords in a php session (not a cookie, so non clientside)? Is there a better way? Or should i just ask my user every time for the password?

I encrypt the privatekey of rsa with the userpassword using phpseclib. Everytime I want access to the key I need the password. I have two options: Either I store the password or the key which is I think both not really good. I can't use the passwordhash for the encryption, cause the hash is stored in "plaintext" in the database...

 Answers

1

Keeping plaintext passwords anywhere in any capacity is usually a bad idea. Sessions are safe as such, but only as safe as the rest of your server environment. Administrators or other users both legitimate and nefarious may have access to data stored on it. You never want to handle the secrets of your customers if you can avoid it; that also means you want to avoid seeing the user's password under any circumstances and you should build your code in a way that the plaintext password is as short lived as technically possible.

If you need to use the password for something during a session, you should architect your app so it never uses the plaintext password, but use a key derivation function to derive a key from the password which you then use for your sensitive tasks. This way there's a lot less chance to expose the user's password. Remember, the only security the user has is the secrecy of his password that only he is supposed to know.

Thursday, November 24, 2022
5

After revisiting this topic several times, I have figured it out. There were two problems.

  1. session_regenerate_id() must be called before any HTML output is displayed and/or headers are sent. (It needs to be called as one of the first functions, just like session_start()).
  2. Order matters. session_name("TMU") needs to be called BEFORE session_start() to have the desired result - I didn't catch this before.

Basically what was happening to me was calling session_name("TMU") after session_start() was causing it to set TWO session ID cookies - two sessions - one named TMU the other just the default PHPSESSID. Changing the order fixed all my problems and regenerating the ID / destroying the old session works as expected now.

For anyone having problems doing this I suggest you echo out the $_SESSION and $_COOKIE arrays to see what is happening in your particular application.

Tuesday, October 18, 2022
 
3

It's hard to quantify in exact terms. First, remember that cookies are transferred between the client and the server in every single request. That's potentially many opportunities for someone to intercept them. Just assume that cookies will be intercepted at some point by somebody.

Storing the username, userid and (encrypted) password in the cookie:

  • leaks information which may or may not be useful or usable for nefarious purposes; i.e. for a successful login you need a username and a password, and you are waving both high up in the air shouting CAPTURE ME, the username even in plaintext
  • relies solely on the secrecy of your encryption algorithm for the password; if it becomes known, you have quite a security problem
    • since the encrypted password is known, an offline brute force attack can be mounted against it to reveal the encryption algorithm and plaintext password; this attack may or may not be purely theoretical, the fact that it exists at all should bother you
    • if it is possible at all to decrypt the password, you have already lost; the password is a secret only the user alone should know, not even you want to know at any point what the password is; if you do know the password, you have a giant responsibility to safeguard it, certainly you do not want to send it back and forth over HTTP the whole time; ? see password hashing
  • gives you no control over anything, all login information rests with the client (i.e. what do you do if you know any of the above was compromised?)
  • does not let you change passwords without invalidating all active logins

On the other hand, using only a meaningless session id:

  • reveals no useful information in the cookies
  • no opportunity to crack or brute force anything of value
  • server holds the ultimate power since sessions can be revoked at any time
  • it's simpler (simpler is always good in security)
  • using a full session with server-side state allows you to escalate privileges; e.g. require the user to have actively logged in with his password within the last x minutes from the current IP to allow him to change his password or email address ? provides security even if the session cookie should be hijacked

In short: session ids present no attack surface at all, since they're inherently meaningless. Userids, names and passwords present a very juicy target. Just from those basic points sessions should seem a lot more appealing. Assuming a perfect implementation with otherwise perfect security, both should be rather secure. However, you do not know what insecurities you have, you won't have perfect security. Assuming this, knowing this, the simpler system with fewer caveats should always be preferable.

Sunday, August 21, 2022
 
2

Windows historically didn't save command history between sessions, only within the session. This was true for the command prompt and for PowerShell.

As Bill Stewart pointed out, Windows PowerShell on Windows 10 and Windows 2016 includes PSReadline by default, which does save your command history between sessions. You can see this by looking at the file here: (Get-PSReadLineOption).HistorySavePath.

But even if it's set to off, or on an OS version that didn't offer the option, that doesn't mean entering a plaintext password as an argument is a good idea.

If you must offer that, you should also have a way to have the program prompt at run time.

For PowerShell and other .Net applications, you have another issue with accepting plaintext passwords: they linger in memory and there's no good way to explicitly clear them.

This issue is two-fold: strings are immutable in .Net, which means you cannot just modify the string with nulls or random characters to clear it in memory (you will actually be creating a brand new string), and on top of that you cannot control when a specific object will handled by garbage collection, so you can't explicitly remove it.

This is why the SecureString class exists, but not everything can use this.

In PowerShell, there is a PSCredential object which stores a user name in plain text and a password as a SecureString. This should always be used in PowerShell, and should be the preferred argument type (in lieu of a separate user name and password).

Most commands in PowerShell that require a credential take it as this type of object.

You can retrieve a plaintext version of the password easily with this object as well. Doing so then puts that into a managed string and you get the risks I mentioned above.

In my opinion though, it is still preferable to use a PSCredential object in these situations, right up until the point you need the plaintext version. It helps to maintain the standardization of this type in both a built-in/'official' capacity, as well as in user-defined commands.

This type is also easily serializable with Export-Clixml into a form that is encrypted. This can give you a really nice way of providing an automated option to use stored credentials in scripts, with nothing in plaintext, and no prompting or user intervention required.

Tuesday, September 13, 2022
 
2

Sessions are usually keyed to IP addresses at some level somewhat preventing session theft.

Beyond that, the session ID doesn't contain any personal information; your password, even salted and hashed does. Passwords, salted and hashed as they may be, can be reused; session ID's can't. Once the session is over, it's over, you need a new session ID to be able to impersonate the user again.

Monday, November 28, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :