views:

343

answers:

9

Possible Duplicates:
What are the security concerns I need to consider while coding?
What should a developer know before building a public web site?

If you're not able to or just plain aren't going to use SSL then you should:

  1. Not be transmitting sensitive information.
  2. Using SSL does not make your website totally secure (man-in-the-middle-attack).

If, however, you still insist on attempting to secure your website without SSL, or you just need some general website security tips:

  1. Cipher form information using Javascript (XOR etc..) before submitting (keep honest people honest).

  2. On your login page transmit an SHA (> 1) hash of your password in a hidden field and clear the password field using the onsubmit event of the form. Don't just send the password in plain text. Again use an sha (> 1) javascript hash.

  3. Don't pass information around using the query string. If you insist on using the query string, use AES encryption with a per session key and initialization vector.

  4. Don't populate html controls that store value/text pairs with plain text ID's. Things like AccountID/AccountName. Instead Populate them with (AES Encrypted ID)/AccountName. And for Pete's sake don't concatenate and display the ID and it's associated Name string.

  5. Authenticate on each request. In other words, if the session is still valid then you should have a session variable to indicate if the user has been logged in or not. If not, redirect or transfer to the login page.

  6. For each request, if javascript is not enabled and you need javascript, simply display a link to or redirect to a page that explains how to enable javascript in various browsers.

  7. Create an error page that doesn't display a stack trace or any other information about the site. It simply has a smiley face and a friendly message on it. Redirect all errors to this page.

  8. HTMLEncode all fields before storing them in a database or re-displaying the information.

  9. If page requests or login attempts happen too fast, use captchas to verify that the user is human.

  10. Separate the database server from the web server (i.e. don't run them on the same machine).

  11. Store a hash of the salted password and the salt, instead of storing the plain text password.

  12. Secure your database server (topic of another discussion).

  13. Secure your web server (topic of another discussion).

  14. Validate user input (GET and POST data) before making use of it. (Range check etc..)

  15. Use parameterized queries instead of concatenating strings of SQL. This avoids having to properly escape the SQL string for the database in question.

Anymore website security tips?

+1  A: 

I'd rather suggest you to develop without using JavaScript. I have it mostly off for the sites I don't know or trust (that's majority of them), and I have no intention on turning it on even after seeing your friendly page with explanations how to turn it on.

To the point:

  1. What for?

  2. Why? Most sites don't do it and operate smoothly

  3. Why? Are you so paranoid?

  4. Yea, FBI is watching all your IDs

  5. That's a good one. Actually, store some kind of authorization key an validate it on each request. You can also consider storing IP and the USER_AGENT transmitted during authentication attempt and comparing all subsequent requests with it along with the checking of the authorization key.

  6. After such a redirect I will likely close your site and continue to the next one

  7. Very good. Also, if you detect some really illegal request just drop the response. No point in wasting traffic for those who want to break your site.

  8. Encoding fields before saving them in the DB is a really bad practice. You won't be able to analyze test results in test queries in editor. Moreover, if you have fixed length text types in your tables, the actual input length after encoding will unpredictably expand resulting in the loss of data. Only encode before displaying the user-entered data back.

  9. Agree

  10. Yes, if it's not your blog and you have resources for two machines

  11. Absolutely

12/13. Sure, hard to contradict


EDIT: Try to put some [invisible] limits on all user activities. Limiting login attempts is straightforward. Try to come out with some system of limiting amount of requests, so that the automated bot cannot just crawl your site and download all its content.

User
Yes, however, if you were in a business to business situation, it would be a different story. Thank you for your input.
That you Mr. Mastermind. Your opinion is respected. Do you have any other tips for website security?
A: 

Maybe something like:

  • Check user-controlled parameters before you use them

For example:

<?php include($_GET['page'] . ".php"); ?>

would be something very very dangerous... So in this case one should better use somethink like the following to make sure that the file is on your server:

<?php
    $fname = $_GET['page'] . ".php";
    if(is_file($fname))
        include($fname);
?>

This is also important when it comes to database-querys...

Kevin D.
Excellent tip. Thank you Kevin.
Checking whether the file exists before including it doesn’t make it more secure. It just prevents some error messages for when the file does not exist.
Gumbo
No, you are wrong!In the German Version of php.net there is written that is_file only works with local files so you cannot use it for remote access what makes is_file perfectly adequate for security in this case.
Kevin D.
http://example.com/?page=/etc/passwd ...
Kris
@Kevin D.: Sure, `is_file` does only work on the filesystem. But there it just checks whether the file exists or not. And that’s it. No checking whether including that particular file was intended by the application/author. Take example.com/index.php?page=index as an example and you have a perfect infinite recursion.
Gumbo
Okay, with that one of course you are right...I had a limited view on it...I apologize...(But 'is_file' can indeed prevent spammers from abusing your website for their goals...)
Kevin D.
@Kevin D.: Spammers? How would that prevent spam?
Gumbo
I meant eMail spammers that use security holes like that to send eMail via your page....
Kevin D.
A: 

Using "secret questions" is not highly reliable, as discussed in this article about a recent study.

DOK
Very interesting. Thank you DOK.
A: 

There is an open source database firewall called greensql. It will help you protect from sql injection attacks. It is very simple to install, its free. I recommend it.

maozet
Thanks maozet! I'll look into it.
+2  A: 

About your 1st #2, SSL/TLS does prevent man in the middle attacks as long as the end points (client & server) have not been compromised. You are right in SSL does not secure the site, what it really does is secure the communication between the two endpoints.

Looking at your list, it looks like SSL would take care of 1 through 4. As a site admin, if you don't use SSL, don't look to Javascript to solve those problems.

A perfect example of this is if there is a man in the middle attack and you are not using SSL, the attacker could change the javascript or page content in transit and simply remove the hashing or any other security feature you try to implement via Javascript. Once this is done, they have full access to anything the user decides to give them.

Mitch Baker
My sentiment exactly. Thank you Mitch Baker. Your input will greatly enhance our efforts.
A: 

MITM attacks are not feasable with cert issued by trustworthy third parties. (Hopefully this is your browsers root cert list:)

Even a self-signed cert will at least prevent passive MITM.

My personal condensed 'duh' list:

  1. Don't create a possibility where user input can ever be trusted to process actions not specifically authorized to the user.

  2. The system or framework I'm using should escape everything properly by default so that XSS/Injection simply is not possible unless I explicitly "ask for it". If it does not do this I have no business using the system or framework. (Specifically DO NOT use PHP,ASP..et al.)

  3. Be mindful of CSRF issues when making decisions based only on browser provided state.

  4. Never loose site of the root sources of trust in the system - any imtermediate tickets used as proxies for the source must themselves be at least as trustworthy as the source itself.

  5. Don't waste time on security theatre (Intermediate firewalls, input validation, separate systems, virus scanners) ..etc. These are only marginally useful to mitigate the failure of a flawed system which all avaliable time should be spent to make unacceptable in the first instance. None of these concepts are capable of providing guarantees (and can actually introduce flaws of their own) regardless of what the monkeys behind them tell you.

Einstein
100% agreed. Thank you Einstein.
+1  A: 

With regard to suggestion 3:

On your login page transmit an SHA (> 1) hash of your password in a hidden field and clear the password field using the onsubmit event of the form. Don't just send the password in plain text. Again use an sha (> 1) javascript hash.

Substituring the password with a hash of the password achieves nothing. Instead of recording your password I now just have to record the hash. That is not any more difficult.

Also, if someone is making a hobby-site (a site without SSL cannot pretend to protect any important data) it would be nonsense to suggest using a hash function stronger than SHA-1, despite the hysteria that recently broke out on Planet Debian, where people made post after post about how they were changing their PGP keys because they had hear that SHA-1 is broken. There has been a presentation at EuroCrypt that announced that it should be possible to find a SHA-1 collision in 2^56 steps, instead of the 2^80 steps you would expect for a 160 bit hash. But no collision has been found yet and brute-forcing your password is still much easier.

Martin Geisler
"Substituring the password with a hash of the password achieves nothing. Instead of recording your password I now just have to record the hash. That is not any more difficult." Interesting, could you further explain your reasoning.
Instead of a plaintext password logging you in, it's a hash. I can just intercept your hash, same as could your password and post that to the forms destination. It doesn't make it more secure.
Rich Bradshaw
Not even through obscurity? I shall immediately and without question delete item 3 from the list. Thank you Rich Bradshaw and Martin Geisler for setting the record straight. Your input has helped us greatly.
+2  A: 

This is kind of similar to Kevin D's answer, but I think I'll generalize it a bit more: never trust any kind of form data, even if it should already be "validated" client-side. Sure, you might think that, for example, if you have some data that is given via radio buttons, there's no way that a user could send invalid data, right? But think again: values can easily be spoofed by clever users.

In other words, if you're pulling data from GET or POST parameters, always check it and sanitize it. No one will be able to fool your site with Firebug if form data is always validated server-side.

(If you don't believe me, here's a real life example from The Daily WTF.)

htw
Wow, hilarious story, thanks for the link htw.