Scenario: a web application written in PHP utilizes an Amazon Web Service and must keep the Access Key ID and a Secret Access Key handy in order to function. Are there current recommendations and/or API's out there for storing this data securely?
My thought is to symmetrically encrypt it into a file based on a key created from local server variables. That way it's [hopefully] gibberish if someone gets a copy of the file through FTP, lost laptop with files copied, etc. The concern I have is that a skilled attacker could just upload their own script to decrypt it.
This seems like a common situation and one I've never achieved a comfortable solution for. Obviously I can't use a one-way hash, because I need the original data to create a HMAC to send to AWS. Links to related S.O. questions are very welcome.
Ah. The question of security.
I think the question you should be asking here is what do you do with say, for example mySQL passwords in your php config files?
To be quite frank, I would say that if someone managed to get a copy of your files, then your security needs rethinking anyway. For my own use, I generally only keep the passwords in one place, (on the server where they should be used) and make sure that I use a randomly generated password each time (paste it into the config file, and voila!)
To be honest, if it's not your own host, ANY sensitive data can be compromised.
If it is your own host, I'd suggest using proper permissions within Linux, and PHPSuExec to make sure that only the scripts that YOU write can access the files.
Anyway, to answer your original question, your AWS Access / Secret Keys are just the same as a MySQL password, Ok, it has the potential to let someone access your service, but it doesn't give them access to your personal details. Even with symetric encryption, if your script has a security hole, the information can be accessed.
Put simply, you take a risk when you put these keys anywhere that is accessible to anyone but you. How much do you trust Amazon's servers not to be compromised?
My suggestion would be to try and add as much security as you can, but keep an eye on your account, I'll generally have a cron job running to send me an email with changes to my S3 account (new files uploaded, new buckets etc etc) and from that I can tell what's going on.
There is no easy solution, it's a mix of securing each seperate layer of the System. I mean, if you use symetric encryption, the password for that has to be stored somewhere, right? or are you going to type it in every time ?
Hope this helps
My thought is to symmetrically encrypt it into a file based on a key created from local server variables. That way it's [hopefully] gibberish if someone gets a copy of the file through FTP, lost laptop with files copied, etc. The concern I have is that a skilled attacker could just upload their own script to decrypt it.
This wouldn't hurt, but ultimately it is just security through obscurity as somebody who can read the file can probably also read and reverse engineer your code. Short of typing in a password or otherwise providing a secret every time the server starts, encryption isn't going to help. It just shifts the problem to how will you protect the encryption key (which also needs to be accessible to the server)?
You have to harden and design your application and server (don't forget the OS, and remote access to the OS) so that nobody unauthorised can read the files on the system in the first place.
If you're worried about someone getting physical access to the box, concentrate on physical security to stop that happening.
I use symmetric encryption like you suggest. When I start my server I need to give it a key to decrypt the files containing the authentication data.
Of course a hacker could do a memory dump and read the password that way but that's quite a bit tougher than reading a cleartext file. There's no perfect solution, security is always a compromise between risk and ease of use.
So server security is still the key issue, its just a question of how much security is enough. I'd suggest looking at Bastille Linux or something like that to harden your server but that's another topic altogether.
Related
I have a web app that uses AES encryption, everything works well, but I hard code the key in the php file. Here is an example ... encrypt($msg, 'password'); ... It calls my function and sends the password as a second parameter. The glaring flaw is that if someone accesses my server and looks in the php code they can easily take the key and decrypt the database. Should I be calling the password from an alternate server from an alternate database? Anyone have any simple ideas to protect the key? btw. I am stuck using one key for all the encryption because of the nature of the application.
This is the same chicken and egg problem which crops up all over the place in IT.
I expect this will be closed as a duplicate of something else - but its quicker to answer than look for duplicates.
There are different ways to mitigate the risk but none fix the problem. Which solution is right for you depends on what your specific risks are - are your backups encrypted / secure? Do you want the application to recover automatically from reboots? Is your application running on a system which is able to prove its identity/integrity to another machine? Does it run as part of a cluster.....
There are only so many places you can store data:
on another machine (access depends on an authentication mechanism)
on the filesystem (secret will be visible to anyone with access to that filesystem or a backup of it)
in memory (secrets are lot at reboot, and there is limited scope for protecting them from someone with access to the machine).
Don't feel bad. HSMs go to extreme lengths to provide security for secrets where it is practical to do so - but will hand them out to any authorized client (and the authentication schemes are not the most reliable). The model for managing master keys used by most password managers is truly awful.
Another key point is that a lot of the solutions which provide a moderate amount of protection are far from simple. I am current playing with the idea of writing my own password manager where the master encryption key is also encrypted with a key composed of each users password and a secret stored in memory on the computer. But this has issues around how to inject the system key at boot time securely and dealing with password resets.
The Linux kernel now has a virtual HSM capability which allows you to restrict data stored in memory to specific processes, process groups or users - but its not portable across operating systems.
My question is that,is using our real username and password on phpmailer for sending message,is safe to use?,anyone can steel our username and password,from my php script.is any solution is there,except hiding view source code.
IDs and passwords for email are much the same as IDs and passwords for database connections. Generally speaking, nobody other than you (and other sysadmins on the same server) should be able to see your source code, nor these passwords. PHP code is not visible to people visiting your site (unless you have misconfigured your server).
That doesn't mean you should not take precautions; There are ways of making this information available to your application without leaving it in source files, for example by putting them into .env files which are loaded into your environment (using something like Env), but are not actually part of your code base.
This allows you to keep passwords out of git repos, and should be stored outside your web root.
Furthermore, these files can be encrypted, but that really just moves the problem further along because at some point you'll need to store the key to decrypt it with.
So I am encrypting data, storing it in the database, and decrypting it, using mcrypt.
I am wondering if it's safe to store the key for encryption in a php file outside of the public_html directory?
The reason for storing it in a file is that it needs to be used for multiple encryptions, so that multiple users can decrypt some data, and I figured storing it in a file is more secure than in the database table, right next to the encrypted data.
What are ANY potential security risks? Is it at ALL possible for a hacker to gain access to this file and thus the key?
Storing it above the public_html is a good idea. Your file should have the correct permissions configured so that only the web server or users that require it can read it.
An option is to split the key up and store in different places, for example part of it in a file on the file system, and part in the database. The benefit of this is it's harder to get the full key for an attacker because they need to access both the file system and the database.
Also consider your server environment has an affect on security, for example shared hosting is less secure than a dedicated server.
No one can say that it's impossible for an attacker to access the key because that depends on your entire server setup and config. Server's are most often compromised through vulnerabilities in software such as web servers, so you should follow good security practices such as keeping your software up to date.
If your server (as in its OS) is compromised, it is "game over", no matter whether your key is stored in a file or the database. So yes, it is "at all possible for a hacker to gain access to this file and thus the key" - by breaking into your server's OS.
If apache or PHP are compromised, but not the OS, you end up in a chicken-and-egg problem: If you put your key somwhere, where apache/PHP can access it, it can be taken by whoever breaks into apache/PHP. If not, you can't use it in your webapp.
This leaves only a scenario, where your webapp is compromised, but not the surrounding infrastructure - in this case, a file might indeed be a good idea: Many break-ins (e.g. most of the SQL injection variant) gain access to the DB, but not to the file system.
For sensitive environments we sometimes chose a model, where encryption/decryption is handled via a pair of FIFOs, with the real crypto being done by an external process - this can do some heuristics and refuse decryption on suspicious patterns.
I am planning a project that requires the transmission of sensitive data from the client-side to the server-side, and then on to an AWS Simple Storage bucket.
This is my plan:
Using SSL/HTTP(S), the data can be posted securely via a web form, which is then retrieved by a PHP script on my web-server.
Once the data is received by the server, the PHP script will immediately send it to AWS using the AWS SDK for PHP with a directive to encrypt the data on the server-side with AES-256- See AWS Encryption.
The problem is that between steps 1 and 2, the data will not be encrypted because it has to hit my web-server first for processing. I'm thinking of having the script write the data into a text file on the server before sending it to AWS, then immediately deleting the temp file from the server after it is sent. Is there any risk in doing this? Is there a way to send a file-stream, rather than an actual file to an AWS Simple Storage bucket, thus avoiding the need to write a temp file to the server?
Am I overlooking better methods of achieving my original goal of data transmission that is encrypted 100% of the way?
If you're committing something to disk, then a sufficiently motivated attacker can arrange to steal that file the moment it hits the drive platters - it's fairly trivial to get notified of any changes to a disk/directory on most any modern OS, so they can simply monitor your temp directory (wherever you're writing those files) and copy them out.
Even if you immediately delete the file, the file is still present in the storage system in various caches, and as "can be written over anytime" sectors on the disk platter. Until the data's been overwritten by something else, an even more dedicated attacker can still retrieve the file even after deletion.
Beyond that, someone with enough access rights could simply reach in your PHP process's memory space and extract the file from there.
So.. the question you have to ask yourself is "what is my threat model"? And "what data am I storing in this file?"
If the data includes credit card numbers, then you're already in violation of PCI standards - the CC number can NEVER be stored anywhere in plaintext/readable format.
Not an encryption expert, so can't help there, but...
If you don't trust the webserver's physical security enough to rely on standard Unix system hardening, you probably need to get a better webserver.
Any encryption you use on the intermediate server will suffer from the fact that the decryption key must be stored on the server in order for the data to decrypted and then sent on to AWS. If the key is stealable, the data is not secure even when encrypted. If it's not stealable, then how can the data be stealable?
Forcing the system to use only RAM with no possibility of writing to disk is tricky and ignores the fact that someone with root access can also read data (with difficulty) directly from the RAM of the webserver process before it gets encrypyed.
Once someone has root, there's no real defence unless the key is stored elsewhere, so I would recommend using a public key in the browser and a private key within AWS. Forget about decrypting it half way. If AWS can't do that, then don't use it. This post suggests that they do, with a tutorial here, but you'll need to use Java by the looks of it.
I probably need to protect a LAMP based server against being stolen or hijacked by a third party.
My idea is to use hard encryption to encrypt all data records using a master key, which can't be recovered, if the server shuts down. Thus, the master key can't be stored in the file system.
I'd provide the master key using a secure channel if the server runs.
The server should be able to use it, as long as it continues to run. If the server fails, the key should not be recoverable.
What would be the best solution in this case (shared memory?).
Do you mean you are trying to protect a physical server against theft? If so, I suggest that beyond the operating system's built-in security, the primary mechanism for physical security is not code-based at all, but rather a good old fashioned lock and key. Wonky home-brewed encryption mechanisms are not the answer - security through obscurity is not security.
Please provide more details on the kind of application and what data needs to be protected.
A pretty common way is:
run a standard linux distribution
have a root password and/or restrict login to ssh only
ssh into it when they system is up
mount the encrypted drives (provide the keyfiles over ssh or something, but only temporarily - delete them afterwars - you can have a script for that that downloads from an external sftp server that you can activate/deactive for the process)
when the server stops (power down etc) the drives get dismounted and the data is safe
when the server runs there is no way of getting to the data
additional chassies intrusion can be set up but is not really necessary and can be worked around by by a trained technician that really wants to
edit:
it is theoretically possible - with perfect knowledge of all involved chips and extremly high sensitive equipment to physically hijack into live conductor paths and catch some data. (i once saw a demonstration on ata-33 PATA cables.
the server would have to be put on a mobile power supply and brought into a fully equipped lab for that.
but you can totally avoid that if you have a system level encryption layer. theres no equipment on earth that can do somthing then.