Making Your Website Secure

So you’ve got this really cool website. It’s an analytics platform with a bunch of snazzy charts and graphs, elements that fade in and out, and animated icons that really make your site pop. You also have a huge database full of rich data that enables you to produce the most detailed reports in the industry. Because of all this, you’ve been gaining popularity among users around the world and have been getting some attention from some pretty big players. What you may not know, is that you have also been getting attention from another crowd: the malicious user.

Who is this malicious user? It could be anyone. It could be someone looking to steal sensitive information, or it could be someone just looking to mess something up and ruin your day. You won’t know who they are, or where they’re coming from, so your website needs to be prepared to handle anything that can be thrown at it.

I will outline a few things you can do to ensure that your website is secure against outside attack. This is by no means an exhaustive list, and I will not go into painstaking details about any of these methods. This will just be a primer to get you thinking about security and possible methods of attack.

Input validation: Don’t trust user input. Period. Validate any input you receive from users. Whether that’s a form fill, a POST request, or any other information provided by an outside source. Make sure what you are receiving is what you are expecting. For the best user experience, you would validate within the browser, most likely through javascript. If you do this validation, make sure you do not rely solely on it. Do server-side validation also. Many server-side languages have built-in validation methods that make this fairly simple. If you come across any input that isn’t expected, stop processing that certain request and direct the user to a safe place.

Cross Site Scripting (XSS) Attacks: This goes hand-in-hand with input validation. Cross Site Scripting (or XSS for short) is a when a user injects a rouge piece of code (usually javascript) onto your website and the script executes without your knowledge. There are three types of XSS attacks: Stored, Reflected, and DOM-based. With all three types, the best way to combat these attacks is to escape any user-provided input before the input is loaded into a page. What this does, is turn any special characters into either HTML entities or their unicode equivalents. This prevents the browser from interpreting the special characters as their special meaning and instead displaying them to the page as string literals. Many server-side languages have built-in methods for escaping input into either HTML entities or unicode characters.

Database Injection Attacks: Also going along with input validation is preventing Database injection attacks. You should especially think about this if you are using SQL or any other database language that allows multiple commands to be run within the same batch. If you do not validate and sanitize the input provided by a user, then you could be open to unexpected updates, dropped tables, rouge inserts, or any other kind of behavior you are not expecting and do not want. This could in turn crash your website, or destroy the integrity of your data. A user could place the following code into the Name field of a form: ‘Bob; Drop Table users;’ If you just take this form data and plug it into an Insert statement on your SQL database, you just dropped your entire user table (if you named that particular table ‘users’) and now no one would be able to access your website with their credentials. This leads immediately into another security concern: don’t share or display your database structure to anyone that doesn’t need to know those things. Once someone has access to your table names and fields within those tables, they could wreck your entire database if they have access to an unsecured form.

I only scratched the surface of how to make a website secure, but the information here would be a good place to start on the journey to making your site impenetrable.

Reliability: Creating Rock-Solid Software

What makes great software great? Does it have to look good? Does it have to have a great user interface? While those things are good and will make your application pleasant, those things alone won’t make software great. Software must work, it must work without errors, and it must work every time you try and use it. Some would say that the most important aspect of software is its reliability. If an application doesn’t work, pretty visuals and user interfaces are all for nothing.

So how do we make software reliable? Reliability goes hand-in-hand with functionality, so before you even start, you must decide what the software will do and have a basic plan of how it will accomplish its task. You might even create a barebones application as a proof-of-concept to ensure your methods will work and be a solid foundation to work off of. This initial prototype will actually help in squashing initial bugs and issues that could show up later in the process.

Once you know how you want to proceed and know that it will work, you begin building your application. First and foremost, you want it to function (obviously), but once you get it to function, it must be reliable. Your customers will begin to rely on this software, so it has to work fast and it has to work every time they access it. Working every time is more important than raw speed, so we’ll start there.

Software that doesn’t work is frustrating, but what’s more frustrating is software that works most of the time, but fails you when you most need it. To ensure your application will work each and every time you need it to, you must test it, test it, and test it. Test it until it works without fail, then test it again. Play the malicious user and try to break it. You wrote the code, you know where the vulnerabilities are; exploit those vulnerabilities and learn how to plug those holes. If your app uses forms for user input, validate those inputs, first on the user interface, and again within processing.

Make sure that nothing you can do will send the application into an unusable state. Even when you are sure that there is no way that your code can be broken, add in error handling. In the case that somehow you didn’t consider all possible scenarios that could lead to an error, you must have a way to gracefully handle these rare exceptions. Handling errors can be as simple as a generic message asking the user to please try again, to the most sophisticated algorithms that predict what the user was trying to do.

Once the application works without failure, you must ensure that it runs efficiently. If it feels slow and sluggish, this will be a source of frustration for your users.  With modern programming languages, efficiency of your code base isn’t as much of a concern as it once was, but you should still strive to be as efficient as possible. Simple is usually better. You shouldn’t create some off-the-wall, complicated function to do a task that can be quickly and easily accomplished by a method built in to your language or provided in a library. In most instances, it’s a waste of time. Also, anyone who comes behind you and tries to update your code or do maintenance will need to take time to figure out what the application is doing there.

If you are pulling data from a database, then the efficiency of your database is very important in the speed of your application. Not only do the tables need the appropriate indexes and keys, but the way in which you query the information must also be efficient. Simple and quick queries are best. Get in, get the information you need, and get out so that your application doesn’t tie up valuable resources on you database server. Any complicated calculations should be handled in the application layer, not the database. You should do simple aggregates (count, sum, etc.) within the database, then hand those off to the application to do the bulk of the data processing.

Just because these steps are taken, it doesn’t mean you are finished. Software can always be improved, and as developers we should strive to always be improving.  These also aren’t the only steps to take in making your software rock-solid, there are countless other aspects in which you can improve your application. These two, speed and reliability, are great building blocks to start with, though.