How To Secure Your Sites And Make Life Hard For Hackers
Written by Jan Mulder published 11th Jul 2005 | 11 replies in the forums
Here is a short summary of the things every web programmer should consider if he or she wishes to secure their site against hackers. The advice below is non code specific so it is valid whatever language you use.
I hope others can add specific code examples (such as validation scripts etc...) as comments and replies.
Introduction
Security can be broken down into several areas but there are so many to look at that many users decide that since they can't close all the holes they needn't bother closing any. This is a shame since there are a few areas, when looked at will prevent about 99% of problems. The areas I'd concentrate on first are...
- Authentication
- Session handling
- Input validation
- Error handling
Of course there are many other areas to consider, but if you can close the door in these 4 then you can say your site is safer than most and this in turn will turn a hacker away to other pastures.
So lets have a look at each area in more detail...
Authentication management
Have a minimum username/password length and require at least one letter and one number.
Never ever store passwords (or usernames if you really want to be safe). Nor should passwords be stored with reversible encryption - use a hash function instead. If a user forgets her password, then the password reminder function generates a new, pseudo-random password for the user.
After authentication, track a hashed value based on the session instead of the user's password.
Inform the user if there have been previous invalid attempts to log in to their account.
Limit the amount of bad login attempts and then redirect to a different page.
Prevent and track concurrent logins. This can stop session hijacking and session replay attacks.
Session Handling
Create the session token securely. Implement a timestamp to minimize replay attacks. Also insert a seed and hash it.
Track a user's session time on the server and automatically terminate the session after a period of inactivity.
The "Logout" function should actually terminate the session.
Authorization permissions should be tied to the session, not tracked by separate tokens. This can prevent privilege escalation attacks. You'd be surprised how many people track access permisions using a separate variable like adminlevel=0. Hack this so that adminlevel=1 and your current user login is now an admin login.
Input Validation
This is possibly the most important area and with a little work can have amazing results.
Use strongly typed variables and database column definitions. Store and manipulate numbers as integers or other appropriate numeric type. This means expected input is matched to a data type such as varchar, integer, string, Boolean, or a custom type.
Assign query results to a strongly typed variable. For example, if the application is retrieving numeric values then assign the result to an integer - not a string.
Limit data lengths. All strings should be limited to a length that suits their purpose. A last name, for example, does not need to be stored or manipulated in a variable that uses 256 characters. This can effectively impede the success of a SQL injection attack by reducing the length of the malicious string.
Avoid creating queries using string concatenation. Create a function that operates on variables passed from the application. String concatenation, where a query is formed raw from user-supplied data ("SELECT something FROM table WHERE" + variable...), is the most vulnerable to SQL injection attacks.
Check input for valid content. Eg: a surname should only have letters.
Proactively check input for invalid content. Check for known "bad" characters. Example characters include apostrophe ('), angle brackets (< and >), semicolon, and parentheses etc.
Check input for valid min and max lengths.
Error Handling
Trap HTTP 500 errors whenever possible. return a default page to the user. This page should not contain any internal state information such as variable names, file names, or database queries. Your errors give the game away and tell the hacker where your code can be broken!
Conclusion
The list is by no means exhaustive... but the above should hopefully turn the casual hacker away to look for easier prey. It goes without saying that programmers should incorporate these ideas at design time since it is much more difficult, not to mention more time consuming, to add security measures afterwards to an existing project that hasn't been designed with security in mind.
And now, hopefully, for some code examples...