I’m building a password manager in PHP where the user can store and access a set of passwords using a master password. The database is a simple XML file, encrypted using mcrypt and stored on the disk.
Edit: Each user has its own database file.
The problem is: When the user edits one of his passwords, the database must be decrypted, changed, and encrypted again. Every time the user edits something, I have to know his master password to access the database, so I have to temporarily store the password somewhere on the server or the user has type it in for every change.
I know that storing the password in a session variable can cause security problems, so is there another, more secure way to do it?
Note: I don’t have root or physical access to the server hosting the project, so I can’t change any configuration.
A totally different option is to never have the plaintext stored on the server (neither on disk or in memory). The JavaScript you serve to the client could be used to encrypt/decrypt the data entirely in the client’s browser, based on the master password they enter (so the master password would also never be transmitted- remember a secret between two people is only secret if one is dead! ;).
On the server, you would only store the encrypted versions of the data. The data would have been encrypted by the time they get POSTed to the site. The data is still encrypted when the site servers it to the browser.
This solves a lot of the security issues. An actively malicious web server could still compromise security, but only when the user is actively loading the initial page with the JavaScript. A passive attacker (even if they could see the server’s full system memory at all times) would not be able to do anything to compromise security.
For the user to login to the site (to then be able to access the data cypher text), you could either use a separate password from the master password, or have the JavaScript hash (with a salt!) the master password before transmitting it to the server (which you should still store hashed and salted again).