If you or an organization you work for has a website published on the Internet, then it is only a matter of time before that website will come under attack, by online miscreants hoping to bypass your website's security and cause whatever damage they have in mind.
The reasons for such an attack naturally depend upon the type of website and what the attackers hope to gain by compromising it. For instance, a bank's website is somewhat similar to the bank vaults located in the physical branches of the bank, in that a thief intends to steal money — either digital or cash. The website of a political organization can attract attackers who hold extremely different political opinions, and who wish to deface the website with virtual graffiti. Spammers oftentimes target online forums, with the idea of posting malicious code that sends visitors, against their wishes, to websites selling a variety of highly questionable wares.
Cyber attackers are just as motley as their targets and their intentions. The level of expertise ranges from "script kiddies" who have no understanding of the attack scripts that they borrow or purchase from unethical programmers, on up to "black hats" fluent in all manner of security measures, and how to defeat them.
Countless types of online attacks have been seen on the Internet, at one time or another, and we have every reason to believe that this trend will continue, as the technologies used for creating websites and the resources they host, change over time. In this article, I will examine two of the most common forms of attack against websites, and straightforward ways that you can defend your own website against such attacks.
Possibly the simplest form of attack against a website, is known as "forced browsing", and consist of modifying a URL (the address of a Web page) to see if it yields one or more files that would otherwise not be available due to the website not containing any legitimate links to those files. In other words, the creator of the website had not intended for any visitor to see those particular sensitive files, and yet they are still accessible by using a URL that the attacker has guessed.
A simple example will illustrate this idea: Assume that you have created a website, and published it at the URL http://www.example.com/. Your website uses some utility scripts that should only be run by you and the other website administrators, because those scripts could be used maliciously for destroying data on your website, or accessing sensitive information. Let's say you have stored all of these PHP scripts in a subdirectory named "scripts", and you have no links on your website to any of the scripts. You may be thinking that this is sufficient protection to prevent any unauthorized visitors from running the scripts. But this approach, known as "security through obscurity", is not foolproof.
Imagine, somewhere out in the Internet wilderness, an attacker is running a script that methodically probes every ".com" website, testing every URL of the form http://www.*.com/scripts/, where "*" is replaced by every permutation of letters. Eventually, the script gets to your website (i.e., the "*" is replaced by "example" to test it), and discovers that the URL http://www.example.com/scripts/ is valid. The script informs the attacker, who then tries that URL in his Web browser, and sees something similar to the following screenshot:
The attacker has now discovered your poorly hidden directory, because Web servers are typically configured so that if a directory contains no default index file (e.g., "index.html"), then it lists all of the files in that directory. Consequently, the attacker now knows the names of your scripts, and can run any of them at will. Using our sample names in the screenshot, he could run the first script by pointing his Web browser to "http://www.example.com/scripts/secret_script_1.php".
You can protect against this attack, and it is especially easy if your website is running on an Apache Web server (the most popular one, for many reasons). Simply create a new file in that scripts directory, and name it ".htaccess". Note the leading period, which is characteristic of "hidden files" in Unix and Linux. Unfortunately and unsurprisingly, this is enough to confuse Windows Explorer, which will not allow you to change a filename to one that it thinks consists of only a file extension. Instead, it complains as follows
To bypass Windows's refusal, do File > Save As in your favorite text editor.
The new file, ".htaccess", need only contain a single line:
If your editor is incapable of creating a file with that name, then you can use the Windows command prompt (Start > Programs > Accessories > Command Prompt) to create the file:
echo "IndexIgnore *" > .htaccess
Once that HTTP access file is in place, attackers will no longer see a list of the files in the directory.
Most nontrivial websites make use of a database, for storing information about products, customers, their orders, and any other data that can change frequently. Databases are also the safest place for storing security information, including usernames and passwords. Unfortunately, this storage of user data in your database can be a potential chink in your website's armor.
Assume that you have a database table named "users", containing two columns, named "username" and "password". (I will keep everything as simple as possible in this example.) Your website's pages presumably detect whether or not the user should be logged in to view a particular page, and if the user has not already logged in, the page will prompt her for her username and password. Your code that processes the input will compare the username and password entered with the values in your table. If there is a match, then your code will indicate that the user has logged in. Let's say that the values entered by the user are stored in the variables $username_input and $password_input. (According to security best practices, passwords should always be stored encrypted in a database. But I will skip that for purposes of simplicity. In addition, encryption impacts the effectiveness of some attacks, but I won't be getting into those details here.)
The code that compares the input values with those in the database, is most likely written in SQL, and could look something like the following:
SELECT * FROM users WHERE username = "$username_input" AND password = "$password_input";
If no records are returned by this SQL statement, then you would deny the user access. Otherwise, your code logs them into your system. To the unsuspecting Web programmer, this might look adequate. But as it now stands, an attacker can inject SQL code into your SQL statement, bypassing your security system and/or destroying valuable data. How can they do this? By entering, into a form field, a value that includes actual SQL code, which your website runs inadvertently. For example, the hacker could enter the following two values for the username and password, respectively:
any1 any2" OR "x"="x
As a result, your website runs the following SQL statement:
SELECT * FROM users WHERE username = "any1" AND password = "any2" OR "x"="x";
"x"="x" is always true, so the WHERE clause is always true (because of the OR), and records will be returned. Consequently, the attacker gets logged in, even though he did not have a valid password or even a valid username.
To defeat SQL injections, always "escape" critical characters — such as quotation marks — which means that your code treats them only as literal characters, and not part of your SQL statement. If your Web pages are written using PHP, then run all input values through a function such as mysql_real_escape_string().
Never assume that input values from a user are safe. In fact, just the opposite: Assume that any such input is potentially dangerous, and should be "sanitized" first. This will require some extra coding and extra caution, but it is well worth the effort. Otherwise, your website is wide open to attack.