Ten Rules to Secure By
Preventing all forms of abuse might sound difficult, but it's easier than you think. Just keep the right mindset (never trust the user), and remember the following guidelines.
[list=1][*]If you don't need it, don't build it.
Any feature you build will be abused in every possible way. One of the best ways to prevent abuse is to simply limit your exposure. Take a minimalist approach to building your application. If you don't need it, don't build it. [*]If you build it, someone will find it and figure it out.
Everything you deploy is part of a public interface. Someone will eventually find every file, CGI, and URL on your web server, then dissect it, edit it, break it, send it to their friends, and post it on message boards. Build your application so that the only way it can be used is the way it should be used. [*]Always validate all input.
Just because you expect a number under 10 in a form, it doesn't prevent someone from submitting "War and Peace". Validating all input protects your program from malicious or confused users, and makes it more reliable. Make sure that what a user can enter is what they should enter. [*]If you need to tamper-proof data, then sign it and validate the signature.
If you need the client to hold state on behalf of the server, there is no guarantee that what gets submitted back to the server is what your server generated in the first place. Since you have no control over what the client submits, all you can do is detect whether the data you sent was harmed. Sign the data you send and validate its signature when you get it back. Make sure that only data that your server can accept is the data it should accept. [*]If you need to hide data, encrypt it.
Sometimes people try to hide data by simply scrambling it. This doesn't work and is trivial to break. If you want to hide data, you need to encrypt it using a proven strong encryption function, and treat the encryption key as a secret that no one should ever know. This way only the people or machines that should read the data can read the data. [*]In building restrictions, always use allow instead of disallow.
If you forget to put something in an allow list, then you restrict functionality. If you forget to put something in a disallow list, then you cause a problem. With a disallow list the attacker can abuse anything you forgot to disallow or anything that is made possible by a change in the browser. With an allow list, the only features that can be used are those that should be used. [*]For persistent information server side state is sometimes best.
Any information that you send to the client, such as number-of-tries counters or account balances, can be replayed by anyone at any point in the future even if it's signed and encrypted. For state that you care about preserving accross requests or sessions sometimes keeping a server side table or database is the most effective way to go. [*]Make users accountable by keeping activity logs.
Once you've secured your application, it's essential to keep a good log of activities. A log helps you identify the who and the how of new types of abuse, and helps you iterate to better security. When you find your application is being abused, log forensincs are your key to the crime. [*]Always understand what you're protecting against.
It is easy and enticing to throw security tools at a problem, but to use them effectively you need to understand what you are protecting against. Put yourself in the shoes of a malicious user that is trying to abuse your application, and apply one or more of the other eight rules above to protect against abuse. In other words, make sure that your application can only be used as you intended.[*]Never trust the user.
Or, to be more precise, be very explicit about what you trust the user with. (See 1, 2, 3, 4, 5, 6, 7, 8, and 9). [/list=1]