I read all posts on HTTP over SSL. So far, I know how to get the data securely in a Web form. But I miss the part of recover and keep the data in the same way.
I need in my Website a form to collect sensible data from customers (may be also credit cards numbers for booking, but no credit card authorization process is required) and later keep and read that data in a secure way.
Then, for a basic secure Web application I need:
a) Web site with SSL Domain Validated (DV) Certificate (I don't have fixed IP address. I use basic shared or "virtual" hosting service).
b) Develop a simple PHP & MySQL application that collect sensible data of customers, putting all the app PHP files on the SSL secure folder.
c) All the collected data is gonna be stored in the server MySQL database.
This is the questions part of my message:
1) If I enter later using phpmyadmin to take look at the database over regular hoster services (HTTP), isn't this insecure??
2) What about the hosting administrators? They could also read all sensible data if I use plain text in the database. But encryption methods for data on the server (not only in transmission over SSL) could be enough? Isn't true that the encryption encoding/decoding method could be intercepted by the hosting administrators?? (consider this: the method is inside the application in the same server).
I can't pay the convenience and security of an own server.
3) Considering those things, and assuming that they are true... really matter if I go for a database encryption?
May be I missed something or I misinterpreting some issue.
Thanks a lot for your help and patience.
These shared hosting plans are not really up to the job of collecting credit card numbers - you are betting using a payment gateway and not storing them yourself.
See some regulations on this: PCI
Yes. HTTP is insecure.
Yes, plain text in the database is insecure. Encrypted is slightly more "secure" - it'll deter someone who casually looks through - but anyone with access to the server also has access to the script doing the encrypting / decrypting.
I'd say yes. Encryption in your case won't do a thing against a dedicated attacker, but it'll prevent some sysadmin idly browsing through from immediately having the data without having to make the deliberate step to break in.
I hope you're not storing credit card or other sensitive data, particularly if covered by privacy laws in your jurisdiction. Storing that sort of stuff on a shared server will probably get you sued. If nothing else, storage of credit card data in this manner will be a violation of your merchant account - if they get wind of it, Visa and MasterCard will become unavailable to you.
1) Seeing the data with phpmyadmin over HTTP is insecure, of course.
Regarding 2), if you don't have physical security, then you can't have any security (perhaps with the exception of storing encrypted data which you encrypt and decrypt outside the hosting site).
As your hosting company has access to the computer, they can read all your data.
Having said that, in my experience hosting providers will not do that and try to keep your data safe (because that is their business), pretty much in the same way banks' business is to try to keep your money for you and safeguard it and not taking it.
3) Go for database encryption only if you keep backups. For running the live version it provides little more security (if at all) and makes things more cumbersome.
It is.
They can.
Not really but it could still be a good idea. Someone could get hold of your database and not the PHP source code. Then encryption in the database would be a good thing.
You are correct. The only way to be sure is to run your own server. Also you should know about the Payment Card Industry Data Security Standard.
I think that bobince is totally correct. Public key crypto can help you but keep in mind that you loose comfort of using PHPMyAdmin to view the data - you will see garbage that will need to be decrypted somewhere on the side. See http://www.php.net/openssl to learn more about PHP and public key crypto.
Having an encryption/decryption process entirely on the server is, as you suspect, mere obfuscation and not secure in itself. It can help in cases of a partial compromise, where an attacker gains read access to the database (typically through an SQL injection hole) but no ability to read the site scripts or run arbitrary code.
If you only need to write out sensitive data (canonically credit card numbers) that the server doesn't need to be able to read back in, you can do that with public key cryptography. Encrypt the data with your public key, then read it only on a known-secure machine that has the corresponding private key. This protects past data in the case of a greater compromise where the scripts are readable, and in the case where an attacker gains write-access to the scripts, they at least only get new incoming data leaked, and not the old stuff. Hopefully that would give you time to detect the intrusion and rebuild.
Isn't true that the encryption encoding/decoding method could be intercepted by the hosting administrators?
Yes. But then the hosts have physical access to the machine, so could bang a rootkit on it that intercepted everything the webapp was doing on the fly from day one, if they really wanted. There's no way around trusting your host, so pick a reputable one and don't run sensitive systems on shared servers.
Related
I am developing a SAAS service that allows my clients to connect third party emailing tools (eg MailChimp). I therefore ask to enter their API key associated with the desired service to allow certain actions to be performed automatically on their account.
For that I record in their database their key (s) API and the connection is done. But from a security point of view, if my database comes to be hacked despite all the predispositions taken in terms of security (prepared requests etc) ... These are all the API keys of my clients that are revealed and also email addresses of their own customers that can be retrieved, used, resold ... Because the tools I connect essentially allows to store contacts, organize and send emails.
So I wonder what is the best practice to allow my clients to use the API of their favorite tools without endangering the security of their own accounts and data of their customers (emails, etc). I am aware that currently launching my web application with this data in clear in database would be dangerous.
I thought of several solutions:
Encrypt API keys in database, but I do not see how to test them (decryption) since it's not like a password?
Store API keys on a different database hosted elsewhere, but the problem of encryption remains the same ... no?
Use an OAuth stream: it seemed to be convenient, but all the services I want to connect via API do not offer this and I'm not even sure that this is really suitable for me.
I intend to host my SAAS on Amazon web services, I saw that it was proposing a service called "KMS" Key managament storing but I do not know if it is really adapted once again to my problematic ...
If someone has already had to answer this problem, or knows how to solve it, I want to be enlightened on it!
Note: Sorry for my bad english, i'm French.
All of the solutions you mentioned are somewhat valid and a combination is most likely the best answer. Your application needs access to these API keys so it's not really possible for a hacker to gain full control of your application and not gain control to the API keys. Full control being the key part - you can make it a lot harder to get to them.
Encryption
You would need encrypt them, not hash them, with something like AES. As you need to be able to decrypt them and use them in your requests towards the 3rd parties. This will help you protect against, eg. a database leak - if someone gets your database they would have to crack the encryption to get to them (as long as the encryption is properly implemented). The encryption/decryption key would of course have to be NOT in the database otherwise the whole thing has no point :)
Separation
Different database also makes sense - if someone dumps your main database they won't get to the API keys database and would have to get deeper into the application to access this database (ideally would be a completely separate DB server only accessible from your application).
Architecture of the solution matters too - you can have one server posing as a web-interface that is internet facing and that would talk to the backend server that is not internet facing over some limited (as much as possible) API to lower the attack surface. Only the backend server would then have access to the keys database and would perform the requests to the 3rd parties. Now an attacker has to jump through several servers to get even close to the keys.
Combining the above-mentioned will ensure one would have to obtain full control of your application (and all its parts) to get to the keys, the encryption key and bypass whatever other protection you might put in place.
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.
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.
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.
I'm creating a server(PHP) to store data from android app. With POST query store name, password and email. These data as mentioned are stored on the server (database on hosting).
But I have a lot of questions how to do it correctly:
First is the backend, how to protect data and how to encrypt them?
I know that you can transfer token of android application on the web (server). And there it checked for accuracy, but android application is easy to decompile. How to be in this case?
Also heard of RSA but examples show how the mechanism works. And when used in RSA, I have the private key stored on the server and the public in android application? But what if I we obtain encrypted data from the server on android? I need to decrypt them using the private key. But the key on the server and store the private key on Android ill (paragraph 2, decompiling).
Other...
Please leave comments. Also describe every paragraph of my question, and it is desirable for each paragraph post a link with useful information. Also, I would appreciate any HELPFUL links related to this topic, well, especially your opinion and how best to do it.
I assume that you are trying to create a basic register/login-to-use-this-app mechanism.
Read the PHP FAQ article on password saving on why and how for secure data saving server-side. Basically, to hash (to irreversibly encrypt) sensitive data before directly saving them.
Regarding your second question,
Generally, it is not a big concern on directly transmitting sensitive data between client and server, because there can be these security measures:
Use HTTPS. This will encrypt the stream of data transmission, and it is less vulnerable to the connection being eavesdropped.
You may want to directly send the hash of the password instead of the password itself in the post request, or in other words, use the hash of the user password as the password.
Client frontend
In terms of internal storage, it is not possible to prevent other installed malicious apps from reading and using data you store, unless you (I am not familiar with this) store them in a storage that is only accessible by your own app.
Server backend
There are some servers that distribute OAuth tokens to clients, such as GitHub. However, if you only expect the server login API to be used by your own apps, OAuth isn't necessary in this case, since it is mainly used as a flexible permission bearer which you don't need to concern for your own app.
Instead, the more important thing is how you handle things server-side. For the web API that I once coded for my own server, although I don't expect others to use it, I made the API designed as if it is for the public to use, and pay attention to unexpected client input. This is because clients can be fake anytime, so never trust the integrity of what clients input. (Forgive my obsession, but I even considered backend of my JavaScript on webpages as "clients" to be safe)
I have never used nor have any comprehensive knowledge on other PHP frameworks, but when I work on my website, I would create a safety layer within my own backend code. I separate my backend into two levels, namely the database level and the interface level. The database level should try not let the interface level even get the data that are not supposed to be known by (the current authentication state of) the client, so as to minimize the chance of security vulnerability.
Client-server communication
So this only leaves the problem of data transmission, which is the main point of this question.
As mentioned above, HTTPS would be good enough to encrypt data transmission.
I do not know if this concept is practical, but after initial registration, it might be, if you are obsessive enough, possible to encrypt the data with a timestamp, etc. I am not quite sure about this, but disconnected tokens inspired me on this.
But how much protection you need still depends on what kind of data you are sending. For example, if you are simply tracking user usage, you don't really need a lot of protection for it. Just make sure that the user's original password cannot be leaked by hashing it.
I am working on an Android app that deals with some slightly sensitive information (Names, Usernames, Passwords, Badge number, etc)... As far as code work goes, I know how to connect to a MySQL database with PHP and pull information from it via JSON. I am just worried about the security of doing this. I know there are plenty of Android and iPhone apps that currently implement login systems, but I was curious as to how secure those logins are.
Does anyone know where I can find some information on creating a secure connection to a database with PHP and MySQL for my login system through an Android app? I know nothing is completely impenetrable, but I want to make sure the security of my app is as tight as possible.
As always, I am still getting used to StackOverflow, so if I was not clear or this question has already been answered, let me know!
If you're rolling your own authentication code, it's really hard to say how secure it is. Often people get this horribly wrong and the code has the opposite effect: Instead of securing the site it exposes several severe holes that can be used to hijack it and download arbitrary data.
A development framework like Laravel comes with an authentication system built-in. If there's vulnerabilities in that code, which is reviewed by the community, there's usually an advisory posted so you'll know and can patch as necessary.
If you follow best practices, you should be fine. JSON via PHP or any other language is a good way to go if you want to keep things simple and secure.
Its really hard to gain 100% , but you can use some techniques like
SSL
Session for each user
something like verification code sent through SMS
Encryption data before sent over API calls etc
It is incredibly insecure to connect to a remote db from an app. Think of it like connecting to a database from javascript in your browser, because it is the same level of security.
As an important aside,
slightly sensitive information (Names, Usernames, Passwords, Badge number, etc).
Passwords are not slightly sensitive, they are critically sensitive. I'm not sure if you are implying that passwords are being stored in a reversible format, but they should be hashed.
Anyway, to your main question, instead of connecting directly to a database from the client-side device, you will want to create an API that provides limited access. You would write this in the form of a web service, using some server-side programming. From there, you'll simply use an API key/roles based on the current logged in user. This is the secure/proper way to design this system. You do not want to put db credentials in an app, unless they are for a local db on the phone.
To extend what Gray said, you can pass the JSON data through the URL that you're shipping to the web service that's providing the front end to your DB. There are a couple of other examples that you can find here to start. As pointed out, it's a really bad idea to have direct DB access. Even with a front end, you'll want to ensure that you're doing lots of data checking in the front end. Don't pass direct SQL queries! They're too easy to hack. SQL injection continues to be one of the most successful attacker techniques.
You might consider a Mobile Backend as a Service provider, like Kii, Kumulos, Kinvey, Kony (not sure why they all start with K...), or built.io. They'll cost you money, but save you headaches.
I'm going to be implementing a PHP/mySQL setup to store credit card information.
It seems like AES_ENCRYPT/AES_DECRYPT is the way to go,
but I'm still confused on one point:
How do I keep the encryption key secure?
Hardwiring it into my PHP scripts (which will live on the same server as the db) seems like a major security hole.
What's the "best practice" solution here?
You should think long and hard about whether you REALLY need to keep the CC#. If you don't have a great reason, DON'T! Every other week you hear about some company being compromised and CC#'s being stolen. All these companies made a fatal flaw - they kept too much information. Keep the CC# until the transaction clears. After that, delete it.
As far as securing the server, the best course of action is to secure the hardware and use the internal system socket to MySQL, and make sure to block any network access to the MySQL server. Make sure you're using both your system permissions and the MySQL permissions to allow as little access as needed. For some scripts, you might consider write-only authentication. There's really no encryption method that will be foolproof (as you will always need to decrypt, and thus must store the key). This is not to say you shouldn't - you can store your key in one location and if you detect system compromise you can destroy the file and render the data useless.
MySQL, there is six easy steps you can do to secure your sensitive data.
Step 1: Remove wildcards in the grant tables
Step 2: Require the use of secure passwords
Note: Use the MySQL “--secure-auth” option to prevent the use of older, less secure MySQL password formats.
Step 3: Check the permissions of configuration files
Step 4: Encrypt client-server transmissions
Step 5: Disable remote access
Step 6: Actively monitor the MySQL access log
Security Tools
I agree, but don't the cc if you don't need too. But if you really have too, make sure the file that have it is not accessible on the web. You can write a binary that would return the key. This way it's not store in clear text. But if your server is compromise it's still easy to get it.
the security you need depends on your application. for example, if the only time the cc# will be used is when the user is logged in (thin online store type scenario), then you can encrypt the cc# with the a hash of the user's plain-text password, a per-user salt, and a dedicated cc# salt. do not store this value permanently.
since you're not storing this value, the only time you can get this value is when the user enters their password to log in. just make sure you have good session expiration and garbage collection policies in place.
if this situation does not apply to you, please describe your situation in more detail so we can provide a more appropriate answer.
Put your database files outside computer lets say external hdd and keep it at safe place. Works only if you can develop this project at only place where this external drive is placed :)
Or you can at least protect those files using file system encryption tools like
https://itsfoss.com/password-protect-folder-linux/
In case of production environment I agree with Kyle Cronin.