So I am currently building an application that uses PHP as a web service which subsequently talks to the database in which I store my data. I have chosen to take this route because I am going to have a front-end application that will talk to the database and will be distributed and I do not want to contain any sensitive connection data within it. As of right now, here is how my application works:
1) Client-side application packages data as JSON and sends it via AJAX to the external PHP web service.
2) The PHP web service receives the request and validates it. This validation is done by checking that the correct parameters were supplied via the query string, that the JSON string that was passed along is valid JSON, that the properties within the json_decoded JSON object have the same names as the JSON object that I'm expecting, and that the value types of each property are of the correct type of the JSON object that I'm expecting.
3) If the JSON is valid then the PHP connects to a database and calls the stored procedure that corresponds with the input parameters. The connection data is kept in a separate config.php file and included in the web service.
4) If the database call succeeds, any relevant data is returned to the caller via JSON. Any errors that occur will kill the thread and return an error to the client.
Now, with this architecture, are there any screaming vulnerabilities that anyone sees? In order to better protect the connection data (as that is primarily what I would like to keep hidden from users) I am thinking about doing the following:
-Encoding the data in the config.php in a base of my choosing and then decoding it when connecting to the database.
-Obfuscating both the service and the config files.
Does this sound like enough in terms of protecting my connection values? Is there a better way to store sensitive connection data aside from a config.php file? Is there a way for somebody to easily get access to the .php file that contains the sensitive data? Any advice that you all can give me as to how to further secure this application from attacks would be greatly appreciated.
Best regards,
You could use the PHP OpenSSL libraries to encrypt sensitive data in your configuration files (rather than using security through obscurity). First use OpenSSL to generate a PKCS #12 certificate, then create a PHP page that uses the OpenSSL libraries to import that certificate and encrypt a section, or the whole, configuration file. Then from your PHP code that connects to the database, import that certificate again, and decrypt your sensitive configuration data, then use it to connect to the database. Depending on the size of the data you want to encrypt you may have to envelope the data with AES, then use the RSA keys to encrypt the AES key. This is getting a little complicated for everyone to implement themselves, I think I'm going to write a library for this, thanks for the idea.
Other than that, seems like you have some pretty good security.
From a server point of view...
If your database is on a separate server (which I'd recommend) - lock down the firewall to only accept requests from your web server.
You'd basically only allow access on port 3306 from the IP of your web server. If you're using something like Amazon Web Services this config is really easy to setup.
That way even if someone got the login credentials you'd have another barrier to entry.
Also, I'd make sure you're not on shared hosting, get a decent dedicated server for the web server with a reputable hosting provider that has a good SLA.
Related
I am trying to secure a PHP web application which runs out of a WAMP-style local installation.
Currently, passwords for the app's database are just in the .php files. I thought about encrypting them, but any person can just step through the code to decrypt them pretty easily.
This does not run on a web server, it runs on the user's PC. Has anyone here attempted to secure this type of application, and perhaps shipped a compiled program to return the passwords, or perhaps used an external keystore somehow?
Your thoughts are appreciated.
Clarification: The database is also on the local PC.
There are a LOT of very robust external authentication providers out there. Firebase and OAuth to name a few. Technically speaking, no system is 100% hack-proof, but Firebase and OAuth provide would-be hackers a tough road to success
You can use ENV variable in that case make .env file and store password in that and call the same in application.
You can create environment variable in Apache config file and call from there in your application this is more secure.
There is no way to protect a database connection credentials if you are giving the client / user the source code. Basically if your app can access it and the source code is there for them to use, read, parse then they have the same access as the software does.
Be Clear: This question is not about password encryption/hashing to save into database.
I have developed a PHP application for a client. The application is installed on client machine with XAMPP (placed at htdocs/project_name). Client uses that application locally but the local database is synchronized with remote MYSQL database by Export Report button available on web interface.
My concern is when I store a connection string for remote database in my PHP code the username & password are visible to any guys who can hunt PHP script file and can see it. I don't even wish the client be able to view passwords used for remote connection/synchronization.
How can I achieve this?
You want to give user permission (login data) to connect to the
database but at the same time don't give him permission (login data).
The only thing that is on my mind to store login data corrupted,
and in code decrypt this data with some key hardcoded in the script. This is hackable,
but if the user is not programmed it is unlikely to do this
If you accept Kerckchoff's principle then it is impossible to provide an authentication which is available to a program run by a user without making that token available to the user. If you provided a better description of the problem, specifically the modes of operation you are trying to prevent then we might be able to provide effective solutions (e.g. encapsulating all data access in packages would restrict access to data for specific users).
Current scenario :
There is a webservice (build in php/mysql). User filled data is stored on a remote server.
Issue is user has extremely bad internet connection, webservice is down most of the time. Is there a way to store data locally and sync it when internet is available?
Please note, user might not have database installed on his machine also there is no localserver to work with.
Even if user had some type of RDBMS installed on the box, you probably wouldn't have any way to communicate with it. You can use the HTML 5 Storage API, but it will not solve the connection issues.
And since localStorage (which you probably would use) is available directly only from JavaScript, you would have to make a complicated and fully functional JS application to utilize it.
Note: based on your profile, I would estimate that your JavaScript skills would not be adequate for such task.
If your target audience is mobile users, then you have another alternative: create a native application.
You would still be able to use HTML for the interface (using built in web browser components). But it also would let you have SQLite DB and file storage available on the mobile device, where you can cache the necessary data.
look at the features in HTML 5 for local storage
Typically I would go with IndexDB and then push the local data to the server once the connection is back
http://diveintohtml5.info/storage.html - Should give you a brief about the features and implementation.
I am making a web application and i want it to be secure, so i ll be using SSL and, will hash passwords. But my server is managed by a different company and it's a shared hosting server, they have direct access to database. I want to prevent any possible loss of sensitive information so i am thinking about encrypting all the data in the database.
Is this a good way to keep data secure?
are there any other ways to protect data in database?
I am using PHP, MYSQL, Apache, and Linux
please provide details. also if am thinking in the wrong direction pls tell that too.
Thanks in advance
This is not a big privacy issue
The internet is composed of some few websites / web applications using self hosted solutions with fully personal servers (owned and operated in their own NOC).
Everyone else is using some form or another of shared, virtualized, semi-private, semi-dedicated, collocated hosting. In every case the hosting company has full access to everything, they have physical access to the servers -- no amount of protection can help you there.
Shared hosting might be the easiest to access from the hosting company's perspective. But that's not relevant, their policies should prevent them from operating in bad faith because if they wouldn't it wouldn't really matter if it was the easiest or the hardest to access it would only matter how interesting the data you have is to them (or some random employee of theirs).
Finding a solution to the above non-issue
Some approaches might use:
Mounting an encrypted filesystem as a folder and setting up MySQL to use that folder to store its data;
MySQL encryption functions to encrypt the data in a particular cell or column;
a library on top of SQLite that had an encryption feature which would encrypt the entire database file;
On the other hand if your PHP files would be on the same server and the database decryption password would be stored inside your PHP files, any "intruder" could find it and use it if they wanted it.
You'd have to store the password on a different server or obtain it from the user in order to not have it present inside the local PHP files. This would obviously still be available at runtime; if the "intruder" is a programmer he will be able to retrieve it fairly easily.
I've successfully managed to use POST to run a PHP script on my website, which allows the phone application to add a new entry to the database (MySQL), and delete an entry.
The next step is the one I have been struggling with for the last few hours now, and that is getting the information FROM the DB onto the phone!
I would like a method that initially just connects to the DB upon starting the activity and populating listview or something will all entries, and later down the line I plan on copying the information to a SQLite DB within the phone.
What is the easiest method I can look into for achieving this?
I can be resourceful but I just need to know what I'm looking for!
you have many options.
higher level abstraction over HTTP (REST/SOAP/etc) like already mentioned
HTTP as a proxy for plaintext/CSV data (without abstraction)
a direct JDBC connection from android device to the MySQL
database data export/import
I guess you're looking for option 3. That is syncing a remote database to local (SQlite on android) and then working with local data? In this case you just get a mysql-client jar (JDBC drivers) into your app and you can start. There're some restrictions though, like Sébastien Renauld already mentioned in the comment. Yet, those issues can be worked around, i.e. with custom configuration of MySQL or with option (2) which can be implemented in generic way (write once)
In general you need to create server API: choose some format to talk to between your web service and android application.
Then you'll always be need to request some data from server, that will be returned to you in format described above in a body of network response of some sort.
Next all you need is parse this data and populate to your adapters or whatever.
Note that networking operation might take quite some time depending on your connection, so you can't wait while it ends to show your UI - you need to do this in async manner, and give user a feedback that data is retrieving.
Nowadays json format passed in body of http post requests are quite popular. Take a look at this tutorial on how to parse json on android and this video about how to create json api in php.
Of course you can try to connect to remote MySQL server directly.. It really is more simple solution in some cases (you don't need to code server-side api), but might be not so accessible because standard MySQL ports aren't opened in all networks. Also your API server might hide some implementation details on how is data stored in reality, thus allowing you to migrate for example from MySQL to PostgreSQL without pain for android application.
Don't forget to secure your data from unauthorized access!
EDIT
It's 2017 and what would be the easiest option now is to use opensource project which will provide rest api for your database, for instance ArrestDB or postgrest
I personaly had to develop this following REST API Service (based on Laravel framework, which I call it lRapi) for an iOS and Android devices, and works great (the version in use for the apps, is much more complex).
https://github.com/w0rldart/lRapi
There are plenty Models and Controllers there that you may use to get started. Responses are JSON formatted, with proper headers.
I still have to add some more documentation to it, but there is some on the main example view, which you may access by just setting the virtual host and opening the root page in browser.
Laravel is a MVC PHP Framework, and it's really easy to get used to it.
This a good way to avoid to do most of the work, and just focus on implementing what else you need.