Friday, August 22, 2008

Attacking parameter names

The most obvious and common technique for finding input-based bugs in web applications is to attack the values of the request parameters used by the application. With this technique, the value of each request parameter is replaced (or appended) with a range of attack strings designed to trigger common vulnerabilities, and the application's responses are reviewed to identify evidence of those vulnerabilities. This core technique is employed in manual testing, application fuzzing, and automated vulnerability scanners. And it is capable of finding a majority of the input-based bugs that exist in a typical web application.

A less commonly used technique is to attack parameter names. With this technique, the attack strings are inserted into the name of a request parameter, typically into a newly-added parameter name. In various situations, this technique can identify bugs that cannot be found only by manipulating parameter values. Applications often perform some defensive input validation on the values of request parameters, but perform less rigorous or no validation on parameter names. If arbitrary parameter names are subsequently processed in an unsafe manner, then the application is vulnerable, and can be exploited by submitting crafted input within parameter names. I'll describe a couple of examples of this.

SQL injection in parameter names

Some applications accept arbitrary request parameters and incorporate these into dynamic SQL queries. Consider a preferences page containing a large number of input fields. Submitting the page causes a request with a large number of parameters, for example:

region=uk&currency=gbp ...

which causes the application to make a number of SQL queries of the form:

UPDATE profile SET lang='en' WHERE UID=2104
UPDATE profile SET region='uk' WHERE UID=2104
UPDATE profile SET currency='gbp' WHERE UID=2104

For whatever reason, this functionality is implemented by enumerating all of the parameters from the query string, and deriving a SQL query from each one. The code looks something like this (forgive the simplification):

IEnumerator i =

while (i.MoveNext())
string name = (string)i.Current;
string query = "UPDATE profile SET " + name + "='"
+ Request.QueryString[name].Replace("'", "''") +
"' WHERE uid=" + uid;

Note the sanitisation that is performed on parameter values, in an attempt to block SQL injection attacks: single quotation marks are being doubled up. Note also that no validation is applied to parameter names, probably on the assumption that these are under the application's control, because the application creates the form containing the field names. However, an attacker can of course supply any parameters they wish, and in this instance can deliver a SQL injection attack via parameter names, not values.

XSS in parameter names

Many applications echo parameter names and values into their responses, and yet perform anti-XSS validation only on parameter values. This often arises when applications rely upon generic application-wide input filters or web application firewalls to defend against XSS attacks, but where these defences validate only parameter values, not names. The ValidateRequest feature in ASP.NET behaves in this way, and tolerates malicious input residing within a parameter name.

Application functions which echo arbitrary parameter names are suprisingly common, due to the range of functions which echo the entire URL or query string into the response (into links, form fields, redirects, etc). Consider a simple example which, in itself, is wide open to XSS:


In the default configuration of ASP.NET, where ValidateRequest is enabled, we cannot trivially exploit this using a crafted parameter value, because ValidateRequest blocks values containing HTML mark-up. For example, requesting the URL:


causes the following error:

However, if we instead place our attack payload into a parameter name, then ValidateRequest allows our input through and we hit the vulnerable code:


The moral of the story? If you are a hacker, don't forget to try all of your input-based attacks within an added parameter name, not only within the values of existing parameters. If you are responsible for securing an application, treat submitted parameter names as tainted, and always try to fix your bugs in the code, rather than hiding behind generic application-wide defences.

Wednesday, August 20, 2008

Problem accepting self-signed SSL certificates on FF3

Firefox 3 changes the default handling of invalid SSL certificates, to make it harder for end users to do things they probably don't want to do. If you have used FF3 to access an HTTPS web site via an intercepting proxy such as Burp, you probably know about this behaviour.

The way the feature is documented, FF3 prevents you from accessing an HTTPS site which uses an invalid SSL certificate (such as a self-signed certificate). In order to access the site, you need to explicitly add an exception, which is more cumbersome than simply clicking a "connect anyway" button. When you use an intercepting proxy, your browser receives the proxy's self-signed SSL certificate, and so you cannot connect without creating an exception.

The problem is that, for many users, the feature is not working as documented. When FF3 receives an invalid SSL certificate, many users are just seeing the following error dialog, with no option to add an exception:

You can try to add an exception manually, by going into Options / Advanced / Encryption / View Certificates / Add Exception ...

However, when you click "Get Certificate", you receive the same error dialog as originally, and the "Confirm Security Exception" button is never enabled.

At this point, there is no clue within the product or documentation about how to fix the problem, and I've spoken to several users who have given up and used another browser.

However, you can fix the problem by tweaking FF3's configuration. Somewhat bizarrely, you need to go to about:config and change the network.dns.disableIPv6 option to true:

Having done this, you will now see a completely different error message when FF3 receives a self-signed SSL certificate:

If you follow the "Or you can add an exception ..." link, then everything works as documented, and you can add an exception for the invalid certificate:

I assume that Firefox will fix this usability issue at some point, but in the meantime, if you have had problems accepting invalid certificates, try disabling IPv6 in the FF3 configuration and see if things start working.