Archive for August, 2009
Merging GET & POST Data Leads to Sloppy Programming
Posted by Eric in Opinion, Programming on August 4th, 2009
Under typical situations when writing web applications, there are two ways that you can pass user data to the webserver. GET and POST, which line up with the HTTP verbs of the same names. Of course there are quite a few other verbs, but these are the two which are used more than any others. It is common practice for some developers or framework authors to merge these two data sources into a single common structure and work purely out of that common merged space. It’s my belief that this leads to sloppy programming practices and can have security implications for your code.
GET data is part of the URL, and is visible in the browser. It can also be bookmarked by the browser, and it can be retrieved from browser history. POST data is “invisible” to the user, and cant be bookmarked or recalled from browser history.
To me, GET/URL ($_GET['key'] in PHP, URL.key in ColdFusion) is where you pass application variables such as categoryID, productID, fuseaction, etc. These are properties which are decided and created by the application. User input on the other hand belongs being submitted via POST ($_POST['key'] in PHP, FORM.key in ColdFusion).
There are a few situations where you want to pass user input on the URL. For example if you want to allow a user to bookmark, use browser history, or send another user a URL to a specific result. I do this a lot for reporting and searching functions. But unless you’re specifically attempting to provide this as a feature, user data always belongs being submitted as POST, especially if that page is not a read-only page.
If the page performs any action based on user input other than querying or formatting output, user data absolutely belongs as a POST. Consider this link (which I don’t advise you to click unless you either don’t read Slashdot or don’t mind a mild annoyance): http://slashdot.org/my/logout . This is a security function; it’s much easier to craft a URL and to trick someone into following that link (such as with a tinyURL on your twitter or in a website comment) than to post a form.
Merging your data from GET and POST removes your ability to control and only accept sensitive parameters from one scope or the other unless you break the paradigm of the merged scopes. It also means that as a developer you don’t have to think at all about where your data comes from. That’s a dangerous practice; you should always think very carefully about the path data has traversed before you interact with it. Some data can be trusted, while some data cannot be trusted.
Rather than defaulting to vague data source for convenience of the programmer, you should specifically choose which times you want to accept input from multiple locations and handle those. Your default mode of operation should always be restrictive, opening up only as much as necessary to support your application’s requirements.
ColdFusion: XSS Vulnerability in SerializeJSON()
Posted by Eric in Bugs, ColdFusion, JSON, Programming, Software on August 1st, 2009
There is a minor vulnerability in ColdFusion’s SerializeJSON() method. ColdFusion fails to escape object keys correctly.
Here is a typical example of the expected way to use SerializeJSON():
The output of this is:
The bug is that object keys are not properly escaped, so if you have an object such as a Struct with a specially designed key, you can inject javascript code where it was not intended:
The result of which is:
As you can see, the generated javascript will be parsed by the browser successfully – except where we only intended to communicate data, we instead executed a function.
So what’s the danger?
The problem is that some users may wish to give easy access to GET and POST (URL/FORM) variables to their client-side javascript – maybe some of these parameters affect how you output data for example. If you just SerializeJSON() the URL or FORM variable, then you may unintentionally be allowing user-supplied data to execute in your page context, which can result in cookie stealing, malicious script injection, and other nasty things like that, by the user including javascript code as the name of a URL argument. Actually exploiting that takes some creativity due to ColdFusion automatically upper-casing URL keys, but that’s a one-time exercise which I’ll leave for the reader (sorry script kiddies).
SerializeJSON() should be safe, it should only create a JavaScript object which represents the data, and should not allow for script injection. The fix for Adobe would be incredibly simple; all they would have to do is escape object keys the same way they already escape output strings.
Recent Comments