General rules to avoid getting your website hacked

Miscellaneous Forums/General Discussion/General rules to avoid getting your website hacked

Hi, I'm in the process of learning php and I need a good set of tuts that show the most basic and needed things to avoid people hacking my website due to bad php coding.

For example I remember when people used to hack bb.com and post on the forums as unknown and then there is the recent gallery issues the website was having.

What do I absolutely need to know and do to avoid things like this?

basic one from me: stick an index.html inside each folder so that people can't view the directory listing.

Thanks! Any more?

First off, do some reading on SQL injection and how to prevent it. You need to validate all user input where there is a risk that a user could retrieve information from an SQL database that they shouldn't be seeing, such as usernames and passwords etc. This includes parameters passed from page to page using the GET method.

On the subject of passwords, use encryption. PHP is capable of generating MD5 hashes from any string. So when a user registers, store their password as a MD5 hash. When they log in, MD5 their input and compare that against the hash in the database. The hash itself is next to useless for login purposes. If anybody happens to get hold of the MD5 hash, your login script will MD5 that and result in something completely different, so even that won't help them to get in.

That should be plenty for you to be going on with.

[edit] One more thing - use strong passwords for admin logins etc. Long combinations of lower and upper case characters, and numbers. The longer, the better.

Yep! It's stuff like that that I need to know. I'll make sure to read up on that.

If you are using any kind of user input (eg, blogs, comment boxes etc) which gets added to the page always sanitize the input so no one can enter any nasty code.

Edit: sorry repeating what others said :)

One of the more dangerous things to watch out for is code injection -
http://en.wikipedia.org/wiki/Code_injection


Things from sending queries to your database via some message that gets stored there - all the way to basic html code that they enter (such as a form post) that will get displayed - if the proper measures arent taken the code will execute - even entire scripts will be executed when a viewer loads the page with the injected code..

For example, if this fourm message wasnt properly checked I could type:

<?php
//blah blah (prehapes script to harvest viewer IPs ect..)
?>

And that script would be executed when someone loaded that post.

preventing this is easily done in php with functions such as "strip_tags($message);"

good luck!

An obvious one, but use the latest version of all the software like PHP that you can. I was using an older wordpress and it got hacked.

Javascript should never be used for anything secure. Javascript-based passwords by newbies make me cringe. I've managed to find out someone's sensitive password because of that before - just go to view > page source ;)

basic one from me: stick an index.html inside each folder so that people can't view the directory listing.
Or even better, configure your Apache server to not suck. Seriously. If you have a webhost that by default allows directory listing, you need a new webhost.

The advice on SQL and Javascript injection are fairly good, although today most database frameworks will sanitize SQL, making the former obsolete, and browsers will block cross-site scripting attempts, making the later obsolete.

Regardless a good portion of paranoia will generally keep you ahead of the game. Read up on defensive programming techniques.

Here's a big one:

If possible, put your database connection strings (which would contain DB names + login info) not in the actual PHP content pages, but in a seperate include file which resides in a folder that's not world-accessible...

That way if the PHP parser on the server ever breaks and the server starts spitting out the actual PHP code to the end user (hey, it happens...) then people won't get to see your username/passwords, and also won't be able to pull up the connection file since they won't have access to the folder it resides in.

Here's a good site for this kind of stuff.

Be sure to check out the library section too.

If it's enabled, disable magic_quotes, it's pointless, use mysql_real_escape_string instead.
Never trust user data.
Never trust data that is passed from a web page (i.e. hidden form fields)
If you do use MD5 to encrypt passwords, do it something like this:

$password = "1337d0nk3y";
$salt = "StRInGoFNumBeRSAnDlETTeRs!3784";
$encrypted_pass = encryptPass($password);

function encryptPass($password){
return md5( md5( $salt . $password ) . $salt );
}


There are ways of reversing a straight MD5 (via lookup tables).

Thanks for all the tips. It appears there's quite a bit to read in order to get things right.

My server is safe... i only use HTML.... no inputs at all.

Configure your server *NOT* to display error messages. Look at the logs instead.

There are ways of reversing a straight MD5 (via lookup tables).


Yeah, if someone knows how to use sql injection, i'm sure they are well aware of the online md5 decryptors hanging around..lol.

Encrypting passwords is probobly never worth it. In fact it usually just pointlessly slows things down. If someone can gain access to your database, then they can decrypt the passwords (register, check database value for the password, reverse engineer). That's like saving character information from an online game on the user clients, but having it encrypted....clearly someone is going to figure out how to manipulate the file.

It would be better to ensure that no one could ever gain access to the database in the first place. Anything else is just half-ass.

salting your passwords is another measure. as for hashing, MD5 may work for most cases but 'Secure hashing Algorithm' (ie. SHA-1) is supposedly more difficult to break. Since it's a difference between calling md5(string) and sha1(string) it's not difficult to use in php.

Another general idea is to try to keep data secure over the wire to avoid 'man in the middle' attacks. Sending sensitive information (like a plain-text password) straight from the client to the server is another vulnerability. here's an example for doing a 'secure' login if the server knows the user's password [more applicable for a client like an online game app]:

1. client asks server to login.
2. server 'challenges' the client by sending them a random number. the server remembers this number. Let's say the number was '123'.
3. the client takes '123' and takes their password (lets say it's 'foo') and hashes the combination (ie md5('123foo')).
4. server receives this hash. server grabs their copy of the password and number and creates the same hash. if it checks out, then everything is OK!

advantage? the password is never sent in plain text over the wire. And if someone did get the hash, it would be useless because the 'key' to login changes every time (the random number).

Anyway, the above may be overkill for a simple website, just throwing that info out there :)

OoOoOo! I got one!;

---!!! Dont display your email address anywhere !!! ----

Cant stipulate this enough, if you want a contact page either use a 'human test' or display the address as an image.

Made that mistake once and my spam went up to like 400 a day.

---!!! Dont display your email address anywhere !!! ----

...

Made that mistake once and my spam went up to like 400 a day.


That amazes me. I've left email addresses deliberately in the wild and they've never been picked up. Whenever I have gotten spam it has been due to sites that I have signed up to passing on the contact info (which I can tell because I sign up to each site with a unique email addy).

Im surprised at that, it went mad when i added mine after just a few weeks were talking from +-10 to +-400 a day. I eventually put in a human test and it dropped significantly again after a few months. I now get about 20-50 a day.

I think it also depends how visible your site is from other sites and search engines as the spambots obviously follow links and scan pages for addresses.

You can setup sessions using the $_SESSION array, aswell as storing the session in a database. With this could impliment a 1 time only key system. This would mean that each page load is only good for one viewing. it would involve possibly sending a key along with every page load, or using cookies (probably a cleaner method). Then the script can check if the key matches the one on the server session, if so that page load is valid. You could also store the refering url (easily hacked) to ensure they have come from the same page aswell.

This is the kind of technique you would have to use with AJAX, but it can secure your site aswell. Meaning that a user is not trying to access the page from random places.

You would have to consider the fact that multiple browser sessions may be open on one browser. To get around this you could have a key pool per session, so say people have access to a history of 5 keys.

To be honest this isn't a required security measure, but it does enforce that a would be hacker be using a full implimentation of a browser to do their hacks. They couldn't just write a simple HTTP requester to do it.

I think it also depends how visible your site is from other sites and search engines

Ah. That'll explain it :D