Securing PHP web service calls - php

I'm developing a web site which calls .PHP scripts to inject data into a MySQL database.
Because there is no security on these .PHP scripts, anyone in the world could run them over the web if they knew the proper parameter names and inject data into our database.
I know very little about security so I'm looking for a solution to secure these "web services".
I've read that using SSL may be the way to go but I'm not sure.
If anyone could make a recommendation and point me to a tutorial or website on how to implement this I would be greatly appreciative.
We are using Apache web server by the way if that matters.

SSL will not solve the problem by itself. If someone can hit http://yoursite.com/service.php, they can also hit https://yoursite.com/service.php. SSL simple ensures that the actual data going over the wire is encrypted. But an encrypted injection request will have the same effect as a standard unencrypted one - you'll still have data injected into the database.
What you need is a password system of some sort. A bare bones minimal system would require a secret word to be sent along with each request, and any request without that word gets rejected/ignored. however, then you have to keep this secret word secret, and nothing on the web stays secret for very long.
Next up is assigning a specific key to each authorized user of your service. Nothing would prevent the users from sharing their key with others, but then you've got a per-user key that you can track down and beat up the person who DID share their key.
Past that, you can use HTTP level authentication, coupled with per-user access keys, which should prevent casual poking at the API. Without the http-level password, the API script is not even invoked, and even when it is, the proper API key must be present as well.

Related

Secure PHP password entry possible?

I've been building a website from scratch, and while I have some background in coding (particularly Python and various flavors of C) I am teaching myself html, php, sql and so on as I go.
I would very much like to be able to add an 'admin view' to my website, so that I can add and modify content more easily. I've spent a good amount of time searching for a way to do this securely, hidden behind a password, but it seems as though this is extremely difficult, or even impossible, to do.
With my incomplete understanding of how internet security works, the only way to do this is to have the login php file include a php file from outside the public_html folder which contains the actual password entry, which itself must contain a randomly generated way to modify the password-entering instructions to prevent anyone who intercepts the password I enter from being able to use it later, and which then decrypts the entered password and sends it to other php files outside the public_html folder that contain the infrastructure for the admin view.
Given that I've used several websites that require entering a username/password that use a much less convoluted scheme for securing them, I'm assuming a better system exists. But the main problem of all information from the client being visible to any sufficiently determined attacker seems to render this impossible. What am I missing?
You are right so far, that it is impossible to protect the transportation of the password between client and server, by your own application. If an attacker can do a ManInTheMiddle attack, (s)he could do exactly the same as your client does, or could just strip away a JavaScript which tries to encrypt or hash the user password before sending it.
So the only thing you can do is using an encrypted SSL/HTTPS connection. Most providers offer to install a SSL certificate, but often this is a bit expensive, and sometimes only available in the professional bundle. There are also hosters which offer it for free though.
The encryption of an SSL connection works, because there is already a shared secret. Browsers will install a list of root certificates, and those certificates can be used to set up an encrypted connection.
This is the most important bit: Use HTTPS.
You should use a hash on the password in javascript, before it is send to the server, and only use the hashed value. That way the actual password is not easy to get at. Remember to salt the hash. The point of hashing on the client side is that that it obscures the original password. (Many users use the same password on multiple sites. this way the original password is very hard to get at)
Here is a good implementation of SHA-256: http://www.movable-type.co.uk/scripts/sha256.html
Hash it again at the server side, before you store it, in case someone gain access to your data. Don't forget the salt.
Remember that security is only a matter of degrees :c)
Where you store the hash is less important. Just make sure it's unavailable to the outside.
Use .httpaccess files to restrict access. here are some examples: http://blog.dreamhosters.com/kbase/index.cgi?area=3083

How to make GET web service more secure

I have created web service for android in PHP that uses GET method. Now I want to convert it to POST, to make it more secure. How to convert the application from GET to POST? Is there any other way to make it more secure?
The answer depends on who you want to secure it from. Assuming that you want to protect from network sniffers, SSL is your best option.
POST is the weakest form of "security" you could suggest. All it does it prevent the parameters being visible in a browser's cache history (which doesn't affect you at all in this case) and make it a fraction harder to sniff the parameters over the network (which does affect you). So there's minor benefit (yes, it's worth it), but it's not secure at all.
The simplest solution is to POST using SSL. In other words, as opposed to posting to "http://example.com" you should post to "https://example.com" with a valid certificate on the server. That will encrypt the traffic between device and server. Google for suggestions, or start Secure HTTP Post in Android
Failing that, you could encrypt the data yourself and then send the encrypted query openly as only your server can decrypt it. A little bit of Googling will give you code on how to encrypt in one and decrypt in the other securely - but as a small warning, getting it to work can be frustrating as it won't work until it suddenly does... there's not much debugging you can do when it doesn't work!

Client / Server security from mobile to website

Hey. Am new to the world of web programming and learning a bunch of fairly simple new pieces of tech, trying to piece them all together.
So, we have a simple client (currently iPhone, to move to J2ME soon) that's pulling down lists of data via PHP, which is talking to a MySQL db. I have a rudimentary user/login system so that data is only served to someone who matches a known user etc, either on the website or on the client.
All the php scripts on the website that query the DB check to make sure an active session is in place, otherwise dumping the user back to the login screen.
I've read a little about SSL and want to know if that is sufficient to protect the website AND the data passing between the server and the client?
HTTPS is about protecting data and authenticating the endpoints. You still have to worry about properly authenticating the client to access your services. You also have to worry about vulnerabilities such as SQL Injection and other vulnerabilities that affect PHP. I highly recommend reading The OWASP Top 10 2010 A3: Broken Authentication and Session Management to make sure your session implementation is secure.
Yes, SSL is sufficient to secure the connection between the client and the server, given that it's properly setup.
Your user credentials should also be sent across from client to server over an SSL connection.

SSL to log in, regular http after that... how vulnerable is the data transferred from the database?

I roamed the site for this question using the search engine, and I don't think it's out there. If it is, apologies in advance and feel free to point me to it.
Here is my scenario:
I am setting up a web application, Moodle if anyone is familiar with it, with Apache, MySQL, and php on Windows. Moodle supports enabling SSL for login, but then reverts to regular http after login is established. This is running on an internal network with no connection to the outside world, so no Internet access through this network. All users who use the network have logins, however there are some generic guest type logins with certain restricted privilages. Currently the MySQL database is not encrypted.
My question is this:
If my users do an SSL login, and the system then reverts back to http for the remainder of their session, how vulnerable is the data that is transferred back and forth between the browser interface and the database?
I would perhaps prefer to have all the data encrypted, but I am not sure how bad the performance hit would be to do that, so any suggestions concerning that would be appreciated too. Although I will be extending the functionality in Moodle, I don't necessarily want to have to change it to encrypt everything if already does.
I am new to the world of IT security, and my DBA skills are rusty, so if you give me an answer, type slowly so I can understand! ;)
Thanks in advance!
Carvell
A few things.
The fact that the data in the DB server is not encrypted in no way is a factor in the communication between the User and the Web Server. It is a concern obviously for communications between the web server and the database server.
Your risk point between user and web server is in that packets could be sniffed if a person was able to interject in the middle of the communication chain. However, this risk is mitigated by the fact that your on an internal network.
Therefore, unless you are VERY concerned about the other people in your organization, you are more than likely ok. However, if it is really sensitive data, you might do ALL communications via SSL to ensure that it is transmitted securely. IF you are this concerned, then I would also look at the security of the DB and the communications from DB to webserver.
My concern would be how your authenticated sessions are propagated.
Generally a session works by setting a cookie or appending a session id to any URLs presented by the web site. Once a log-in has been established, often the credentials aren't needed any more, as a session is then linked to the user and deemed to be authenticated, and the existence of the session itself is proof of a successful authentication.
However, as previous posters have mentioned, local network traffic can be available for sniffing. If someone sniffed a session id, they could recreate the cookie or urls using the session id, and simply access the site as that session user, even changing the user's password if that option was available.
I would say that your decision here rests on the security of your sessions. If you have some mitigating factors in place to make sessions difficult to replicate even if a session id is compromised (ie. comparison to ip addresses, etc), or your user accounts are relatively secure from a compromised session (eg. require current password to change account settings), then perhaps SSL after login isn't required. However, if you have doubts and can afford the performance hit, then having SSL throughout the site will guarantee that your sessions can't be compromised (as far as you can guarantee SSL, anyway).
With no internet access to this network, the only thing that could potentially happen is someone else (who is already on the internal network) snooping on another user's HTTP traffic. If someone were to actually do that, and you aren't using SSL, they could read all the data that your website is sending/receiving from that user. But is that actually a concern?
Since you are on an internal network turning on SSL for the whole site should not be that bad performance wise, although it is probably unneccesary.
At the very least, you should encrypt the data in your database.
All sensitive data should be encrypted when transferred over an insecure wire. If you just transfer login details over SSL, all your data is still vulnerable to eavesdropping.
Since the data's not encrypted, anybody with sufficient network access (i.e. physical access) can read the data passing back and forth from server to browser and back. As long as everyone who has physical access to the network also has authorization to read the data, you're probably alright. If any of the information is sensitive, and should be restricted to being viewed by a subset of people who have physical access to the network, then you need to encrypt it.
Anyone on your network would be able to see everyone else's traffic with a network packet sniffer like WireShark. The connection between your web server and MySQL is also in cleartext. MySQL may not actually send passwords in cleartext; it may be a hash, for instance.
If you are really trying to be paranoid, you may not need to run your app over HTTPS. There are other lower-level possibilities like IPSec. Since this is an internal network, you can probably get away with implementing this on all workstations.
Not much to add to the above correct responses. But, one think you can do is use a Threat Modeling tool for your application. That will inform you on the types of threats you are exposing your data to by not using transport level encryption (TLS/SSL). Once you understand the threats, you can decide on an appropriate risk mitigation plan.

PHP - Security what is best way?

What is the best way to secure an intranet website developed using PHP from outside attacks?
That's a stunningly thought-provoking question, and I'm surprised that you haven't received better answers.
Summary
Everything you would do for an external-facing application, and then some.
Thought Process
If I'm understanding you correctly, then you are asking a question which very few developers are asking themselves. Most companies have poor defence in depth, and once an attacker is in, he's in. Clearly you want to take it up a level.
So, what kind of attack are we thinking about?
If I'm the attacker and I'm attacking your intranet application, then I must have got access to your network somehow. This may not be as difficult as it sounds - I might try spearphishing (targetting email to individuals in your organisation, containing either malware attachements or links to sites which install malware) to get a trojan installed on an internal machine.
Once I've done this (and got control of an internal PC), I'll try all the same attacks I would try against any internet application.
However, that's not the end of the story. I've got more options: if I've got one of your user's PCs, then I might well be able to use a keylogger to gather usernames and passwords, as well as watching all your email for names and phone numbers.
Armed with these, I may be able to log into your application directly. I may even learn an admin username/password. Even if I don't, a list of names and phone numbers along with a feel for company lingo gives me a decent shot at socially engineering my way into wider access within your company.
Recommendations
First and foremost, before all technical solutions: TRAIN YOUR USERS IN SECURITY
The common answers to securing a web app:
Use multi-factor authentication
e.g. username/password and some kind of pseudo-random number gadget.
Sanitise all your input.
to protect against cross-site scripting and SQL injection.
Use SSL (otherwise known as HTTPS).
this is a pain to set up (EDIT: actually that's improving), but it makes for much better security.
Adhere to the principals of "Segregation of Duties" and "Least Priviledge"
In other words, by ensuring that all users have only the permissions they need to do their jobs (and nobody else's jobs) you make sure they have the absolute minimum ability to do damage.
If it is on an internal network, why is it even possible to get to the app from the outside? Firewall rules should be in place at the very least.
The best way? Disable direct external access!
If employees need to use it (like an extranet-style site), you should make them VPN in. Through VPN you have a lot more authentication options and most of them are a great deal more secure than leaving your intranet server accessible from the internet.
Another option, and this only works if the data is public-safe, is scheduling your intranet server to push the data to another server that is externally accessible. I say push because you really don't want this server to have access to your network. Let your network server do the work.
The best way to secure it? Don't connect it to a network. Make your users physically enter a guarded room with a single console, running Mosaic.
Oh, you want it to be easy to use?
Always verify every single input that can come from an untrusted source.
Don't trust any data sources.
When storing passwords, ALWAYS store an encrypted hash of the password.
When storing passwords, NEVER store passwords directly.
Never collect or store any data that you don't actually need.
Never allow yourself to be tempted into adding additional bells & whistles.
Read everything that Bruce Schneier has written on security and encryption.
If you forget these simple rules, you could find your application starring on the front pages of newspapers everywhere, just like Yahoo mail.
I would echo #Oli and favour the VPN method if possible. However, if for any reason you need more arbitrary access than this, you should use SSL to secure any authentication. And in addition to password authentication / IP address authentication it would be well worth looking at using SSL with client side certificates.
You could only allow access from internal IPs from the php app itself. Also dont ignore the usual security and best practices. Input validation and output encoding(whitelisting only), user accounts with hashed passwords etc.

Categories