SQL injection attacks are extremely simple to defend against, but many applications are still vulnerable. Consider the following SQL statement:
$sql = "INSERT INTO users (reg_username, reg_password, reg_email) VALUES ('{$_POST['reg_username']}', '$reg_password', '{$_POST['reg_email']}')";
?>
This query is constructed with $_POST, which should immediately look suspicious.
Assume that this query is creating a new account. The user provides a desired username and an email address. The registration application generates a temporary password and emails it to the user to verify the email address. Imagine that the user enters the following as a username:
bad_guy', 'mypass', ''), ('good_guy
This certainly doesn't look like a valid username, but with no data filtering in place, the application can't tell. If a valid email address is given (shiflett@php.net, for example), and 1234 is what the application generates for the password, the SQL statement becomes the following:
$sql = "INSERT
INTO users (reg_username, reg_password, reg_email)
VALUES (' bad_guy', 'mypass', ''),
('good_guy', '1234', 'shiflett@php.net')";
?>
Rather than the intended action of creating a single account (good_guy) with a valid email address, the application has been tricked into creating two accounts, and the user supplied every detail of the bad_guy account.
While this particular example might not seem so harmful, it should be clear that worse things could happen once an attacker can make modifications to your SQL statements.
For example, depending on the database you are using, it might be possible to send multiple queries to the database server in a single call. Thus, a user can potentially terminate the existing query with a semicolon and follow this with a query of the user's choosing.
MySQL, until recently, does not allow multiple queries, so this particular risk is mitigated. Newer versions of MySQL allow multiple queries, but the corresponding PHP extension (ext/mysqli) requires that you use a separate function if you want to send multiple queries (mysqli_multi_query() instead of mysqli_query()). Only allowing a single query is safer, because it limits what an attacker can potentially do.
Protecting against SQL injection is easy:
• Filter your data.
This cannot be overstressed. With good data filtering in place, most security concerns are mitigated, and some are practically eliminated.
• Quote your data.
If your database allows it (MySQL does), put single quotes around all values in your SQL statements, regardless of the data type.
• Escape your data.
Sometimes valid data can unintentionally interfere with the format of the SQL statement itself. Use mysql_escape_string() or an escaping function native to your particular database. If there isn't a specific one, addslashes() is a good last resort.
Sessions
Session Fixation
Session security is a sophisticated topic, and it's no surprise that sessions are a frequent target of attack. Most session attacks involve impersonation, where the attacker attempts to gain access to another user's session.
The most crucial piece of information for an attacker is the session identifier, because this is required for any impersonation attack. There are three common methods used to obtain a valid session identifier:
1 Prediction
2 Capture
3 Fixation
Prediction refers to guessing a valid session identifier. With PHP's native session mechanism, the session identifier is extremely random, and this is unlikely to be the weakest point in your implementation.
Capturing a valid session identifier is the most common type of session attack, and there are numerous approaches. Because session identifiers are typically propagated in cookies or as GET variables, the different approaches focus on attacking these methods of transfer. While there have been a few browser vulnerabilities regarding cookies, these have mostly been Internet Explorer, and cookies are slightly less exposed than GET variables. Thus, for those users who enable cookies, you can provide them with a more secure mechanism.
Fixation is the simplest method of obtaining a valid session identifier. While it's not very difficult to defend against, if your session mechanism consists of nothing more than session_start(), you are vulnerable.
In order to demonstrate session fixation, I will use the following script, session.php:
session_start();
if (!isset($_SESSION['visits'])) { $_SESSION['visits'] = 1; } else { $_SESSION['visits']++; }
echo $_SESSION['visits'];
?>
Upon first visiting the page, you should see 1 output to the screen. On each subsequent visit, this should increment to reflect how many times you have visited the page.
To demonstrate session fixation, first make sure that you do not have an existing session identifier (perhaps delete your cookies), then visit this page with ?PHPSESSID=1234 appended to the URL. Next, with a completely different browser (or even a completely different computer), visit the same URL again with ?PHPSESSID=1234 appended. You will notice that you do not see 1 output on your first visit, but rather it continues the session you previously initiated.
Why can this be problematic? Most session fixation attacks simply use a link or a protocol-level redirect to send a user to a remote site with a session identifier appended to the URL. The user likely won't notice, since the site will behave exactly the same. Because the attacker chose the session identifier, it is already known, and this can be used to launch impersonation attacks such as session hijacking.
A simplistic attack such as this is quite easy to prevent. If there isn't an active session associated with a session identifier that the user is presenting, then regenerate it just to be sure:
session_start();
if (!isset($_SESSION['initiated']))
{ session_regenerate_id(); $_SESSION['initiated'] = true;
}
?>
The problem with such a simplistic defense is that an attacker can simply initialize a session for a particular session identifier, and then use that identifier to launch the attack.
To protect against this type of attack, first consider that session hijacking is only really useful after the user has logged in or otherwise obtained a heightened level of privilege. So, if we modify the approach to regenerate the session identifier whenever there is any change in privilege level (for example, after verifying a username and password), we will have practically eliminated the risk of a successful session fixation attack.
Session Hijacking
Arguably the most common session attack, session hijacking refers to all attacks that attempt to gain access to another user's session.
As with session fixation, if your session mechanism only consists of session_start(), you are vulnerable, although the exploit isn't as simple.
Rather than focusing on how to keep the session identifier from being captured, I am going to focus on how to make such a capture less problematic. The goal is to complicate impersonation, since every complication increases security. To do this, we will examine the steps necessary to successfully hijack a session. In each scenario, we will assume that the session identifier has been compromised.
With the most simplistic session mechanism, a valid session identifier is all that is needed to successfully hijack a session. In order to improve this, we need to see if there is anything extra in an HTTP request that we can use for extra identification.
NOTE:
It is unwise to rely on anything at the TCP/IP level, such as IP address, because these are lower level protocols that are not intended to accommodate activities taking place at the HTTP level. A single user can potentially have a different IP address for each request, and multiple users can potentially have the same IP address.
.jpg)
