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
Related
I am using google's smtp server for sending emails from several sites. The password of gmail account is not encrypted and/or stored in database but hardcoded in the file that handles email forms. Is there any security risks in that approach? Should I create new gmail account for every site or just storing the password in database would be enough?
Storing sensitive data in clear text is never a great practice, but then, most PHP web sites store their E-Mail server data hardcoded in clear text somewhere. What I would never do, though, is hardcode the password to a full Google identity (perhaps with connected AdWords payment information etc.) in a PHP file. Google has a feature for this, more on that below.
In theory, you could store passwords in the database and encrypt them as discussed here for another layer of security but doing that right isn't trivial.
You should at the very least store the PHP file in question outside the web root. That way, even if the PHP interpreter fails (or .php files get disassociated from the interpreter in the configuration), the file can't be exposed to the world.
There's also Google's Application specific password feature. That will limit the damage caused by someone malicious gaining access to the password. In case of a break-in or misuse, you can also deactivate application-specific passwords without having to nuke the entire account.
Those two measures may already give you a reasonable degree of security for your situation.
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.
I have a file setup.php.
This file has the mysql username and password. Is there any method to make it unreadable or encrypt it so that even the admin can not read it, or can read it but still not know the password?
The short answer is that for practical purposes you can make it harder for them to access it but not impossible.
If someone has full access to a server filesystem (eg, with root permissions) then they can read any data off that filesystem, so they can read the code and any data files that you place on there. As the application running on that host needs to be able to use the credentials there's no effective way to prevent someone with full access to that server from reading them.
You could obfuscate them, to make it a bit harder. if you encrypt the credentials in the setup.php file and then placed a decryption algorithm and key in another php file, it would stop someone just opening the file and getting the creds, but it they could always reverse engineer that solution if they're determined enough.
Additionally if they've got full control of the server it would be possible to use a packet sniffing tool to get the credentials as they're used (unless you're encrypting them with something like SSL).
Ultimately if someone is running an application and controls the server you have to place a level of trust in them.
As an aside there's a stackexchange site at security.stackexchange.com that's a good place for questions like this.
Create a new user in MySQL and give some basic permissions for that user. Then you will have two users, your admin account and the user account with limit privileges.
You also can deny view a folder where your setup.php is located doing the same trick, create other user in your OS to limit restrictions to that folder
I have a website developed in PHP. There are 2 classes (in 2 seperate php files) that contain the siteadmin's gmail user id and password (in plain text) and database password (again in plain text). Though none of these classes are displayed on the browser ( like index.php). These files contain only php classes and no html code and the references to those plain text passwords is only through objects of those classes.
Off late, I have started to wonder if this is secure enough? I have tried my best (acting as a malicious person) to try and read the contents of the two said php files but was not able to do so. I am not very conversant with developing secure code, so not sure what should be my approach to make sure that these passwords never get exposed.
Could any one please suggest best practices to develop php code that can contain such sensitive information securely.
Put configurable items in a separate configuration file, above your public web directory
Make sure you have set correct file permissions to your files
Check your web application for local (and remote) file inclusion
Have your server up-to-date
Having your passwords at a safe spot is not the complete solution, you'll need to have your complete PHP application secure, and nobody unauthorized should be able to get root/administrator access to the server.
Firstly, I'd look at using OAuth for accessing GMail if at all possible - it means you don't have to store credentials at all, and provides some level of protection in case your server does get compromised.
I would also look at the answers to this question.
Finally, if your site is on the public internet, it's worth reading up on at least the basics of internet security, and especially securing web applications. There are all sorts of ways things can go wrong. I like the "hacking exposed" books.
Don't store passwords in files, because someone will eventually check that file into source control. Or someone will set a permission incorrectly.
Run the application with its own O/S user account
Put the passwords in an O/S environment variable for the application user (not a system environment variable)
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.