Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Security for storing Data with PHP/PDO

After researching some hours about the topic of securing stored data I am a little bit confused of what is the best way to go now.

I have a databank for my (SSL) website where I am the only one that has access to it (hackers not counted). The login data is stored in a configuration file outside of the document root. In the database I have stuff like names and adresses from my clients and I am now worried that I need to implement all the security measures put forward by cryptography experts like in this answer (How do you Encrypt and Decrypt a PHP String?) or as asked here (Storing sensitive data securely in a database).

Since neither in my PDO/SQL and PHP seminars nor in regular posts here on stackoverflow I see these encryption and authentication methods being used or more specifically e.g. the keys when explaining PDO and PHP commands like INSERT INTO ... etc. I am unsure if it is now necessary to deploy encryption and authentication measures on every entry in my databank (is it even possible to do this afterwards?). The safety measures I have been informed about in the tutorials and articles are to use PDO's prepared statements.

If encryption and authentication is what I have to do, which is probably the case: Would it not be the most convenient and fastest way to simply use password_verify() and password_hash() for every sensitive data entry like it is done for passwords?

EDIT password_verify() and password_hash() are hashing (not encryption) methods, meaning that the data is irretrievably mangled and can only be confirmed but not read.

like image 503
Franky2207 Avatar asked Mar 09 '23 16:03

Franky2207


2 Answers

There are different types of database encryption, and depending on what data you want to protect, and why, you will do different things.

1) Database level encryption / Transparent data encryption

This is where your RDBMS encrypts everything for you at a file level. This means if anyone has access to the hard drive, or back-up media, they should not be able to access the data. See here for how to do it with MySQL: https://dev.mysql.com/doc/refman/5.7/en/innodb-tablespace-encryption.html (note this is not a PCI compiant solution, you'll need MySQL Enterprise Edition or another Enterprise database, or further security measures for that).

Note this does not protect your data if your application is compromised.

2) Field level encryption

You can encrypt data to be stored in any field you like. Here's a good answer that deals with that: https://stackoverflow.com/a/10945097/

The drawback of field level encryption is that you can't then query across the data. In each case you'll need to pull the data into your application, and then decrypt it one field at a time.

Note this does not protect your data if your application is compromised.

Note also the difference between 'encryption' and 'hashing' (password_verify and password_hash are about hashing)...encryption lets you secure data, store it and retrieve it. Hashing by definition does not let you retrieve the data.

In all cases the most important thing is to secure your application. Encryption of the underlying data is very much a secondary concern.

like image 52
DanSingerman Avatar answered Mar 11 '23 04:03

DanSingerman


  • Since your web server (presumably) will have to have access to the data, it's somewhat useless to encrypt it at rest when the web server can (will have to be able to) decrypt it. Why? Because the web server is often the weak link. If an attacker can get access to it, they can do anything it can do, including decrypting the data.

  • Encrypting data at rest is only useful to prevent backchannel leaks, like improperly handled backups (which you're doing, right, right?) which dump the data in plaintext to a file which then inadvertently gets lost somewhere. To prevent that you should use whatever at-rest encryption your database offers transparent to the client; i.e. it's not something you should burden the application logic with if it's not integral to your application, it's something the database should worry about.

  • password_hash is a hash, it doesn't encrypt data, it irretrievably mangles it so it's impossible to get the original back from it. It's great for storing credentials which you need to confirm but not read; it's useless for anything else.

  • The main security points are to isolate your database server "physically", i.e. to not grant any access to it from anything but the web server; be very restrictive and specific about that. That then means the weak spots are at those ingress points like your web server. Ensure your web server is locked down as much as possible, exposes as little attack surface as possible (no unnecessary open ports or running services) and that your application code running on it doesn't allow any exploits (yes, that's the hard part that takes knowledge and discipline).

  • You can further tighten it down by segregating access to the database with different accounts which have different permission levels; i.e. some accounts only have read access to certain tables while others have read/write access to other tables. If you can split up your web server(s) into separate roles which all only need specific limited access, this further enhances security by avoiding vulnerabilities in one part enabling exploits in another.

like image 27
deceze Avatar answered Mar 11 '23 05:03

deceze