Search
Lori MacVittie - Two Different Socks
You are here: DevCentral > Weblogs

posted on Tuesday, April 07, 2009 9:25 AM
Those who cannot remember the past are condemned to repeat it.
George Santayana, The Life of Reason, Volume 1, 1905
US (Spanish-born) philosopher (1863 - 1952)

This oft repeated quote needs to be tweaked just a bit to be more applicable to web application security:

Those who choose to ignore the past in favor of convenience are condemned to repeat it.

Just how many times do developers have to “hack” a protocol that eventually becomes a wide-open hole through which even a blind miscreant could drive a tank before they stop repeating the mistakes of the past?

Not-again-picard I am sure that, given time, I’ll grow less angry about the attitude toward the creation of this but at the moment I’m nothing short of aghast at the indifference toward security with which this risk is discussed.

The “nothing serious” hack is the use of a custom HTTP header, X-JSON, to transport JSON encoded data to be evaluated immediately by the Prototype framework.

This was apparently conceived of in an attempt to avoid using multipart-encoded messages when sending responses of mixed JSON and HTML back to clients. Granted, the developers who looked for a better solution were right: multipart-encoded messages are ugly, difficult to parse, and a pain in the rear to deal with. But “using HTTP headers in a way we shouldn’t” and introducing yet another potential security hole in web applications is just lazy at best and irresponsible at worst.

Perusing the web in search of more information about this potential security risk we find Ruby developers claiming the hack is “nothing serious” even while admitting they shouldn’t be using HTTP headers to transport application data.  About X-JSON header and evil things… from the Ruby Forum:

Let us get something clear - the X-JSON header is a hack. Nothing serious, just a small hack which simplifies returning two types of data (HTML andapplication/json) at the same time. Of course we're using HTTP headers in a way we shouldn't, but has anyone seen how multipart-encoded message looklike? Our header hack is way nicer and technically simpler than that kind of encoding.

The X-something headers are reserved for custom (proprietary) usage. We have the freedom to use them in any way we want to, and we have taken thatliberty to do some highly conventional JSON magic. [emphasis added]

The attitude of simplicity, as usual, winning over security is not confined to Ruby developers as we see from this tale related by a Python developer:

One of the demo sites I was working on this week needed to pass a small amount of JSON back with it's page results. There are a few ways to do this (and I'd suggest this post, "Loading Content with JSON" as a starting point if you're looking for ideas), but for simplicity, I decided to take advantage of the automatic X-JSON HTTP Header parsing feature in Prototype 1.5.0. (The Ajax.Request docs address this capability.) [emphasis added]

I will not disagree with the statement that passing application data via an HTTP header is simpler than messing with the alternatives. But it is fraught with additional security risks.

  1. The client almost never validates input from the server. The server is viewed as a trusted source of data. Recent reversals of SQLi as a method of infecting clients rather than application data, however, should force developers to revisit the assumption that data received from the server should be automatically trusted.
  2. It is moderately difficult for any type of security mechanism – web application firewall, mod_security, code – to ascertain the validity of JSON without evaluating it in the same manner as it would be evaluated by the client parser.
  3. Most secure coding techniques and commercial solutions such as web application firewalls do not expect to find potentially tainted application data hanging out in the HTTP headers. Cookies, yes. Hiding in custom headers? No.

Because of this, the use of the X-JSON custom header to transport [potentially tainted, malicious] application data should be avoided. In fact, if I were to offer an immediate solution I’d say use network-side scripting to remove the offending HTTP header before it is delivered to the client. Use mod_security, use iRules, use something capable of intercepting web application data and inspecting it, then remove any instance of X-JSON you find. Yes, you’ll break the application, but perhaps that’s exactly what needs to be done to get the point across: this is an avoidable, unnecessary security risk against which our customers have no defense. It is irresponsible of us to use it. Find another way.

Granted, the use of JSON as an application protocol has only become widely accepted in the past 18 months, but even so – it is not immune to exploitation. And as it continues to be one of two formats commonly offered by Web 2.0 APIs (the other being the equally exploitable XML) it is likely only a matter of time before it becomes a target of opportunity for those attempting to find easier ways to infiltrate clients and spread their disease.

The reason for the anger toward the casual dismissal of the use of the X-JSON header as “nothing serious” and the failure of developers to see angrymanthis use as the potential security risk it is centers around the fact that this is a completely avoidable risk. This is not one of those “we had no choice” risks; this is 100%, absolutely avoidable. There is no reason that this risk need be incurred, except as admitted to by a variety of developers on the web: it’s easier than doing the right thing.

I’ll say one thing for the developers, they have the basic premise down right. The path of least resistance is the one most people will take. And there isn’t much resistance in terms of security in the use of the X-JSON header and automatic evaluation of potentially tainted application data. So how long do you really think it’s going to take “the bad guys” from deciding that they, too, like the path of least resistance?

One of the Ruby developers stated: “We have the freedom to use them [custom HTTP headers] in any way we want to.”

Freedom incurs responsibility, and in this case it’s the responsibility to ensure that the solution used is secure and doesn’t introduce unnecessary risk. Seems to me that some developers are forgetting that part of “freedom.”

Secure coding in theory is a great thing – but you have to actually apply the principles in the first place for it to work.

Follow me on Twitter View Lori's profile on SlideShare friendfeedicon_facebook AddThis Feed Button Bookmark and Share

Related posts & articles:



Feedback

4/7/2009 11:40 AM
Gravatar I'm curious, what's the difference (as far as security goes) having the JSON data in the header as opposed to the contents of the message? I'd expect anything that could infect the header could also infect the contents of the page. Maybe I'm missing something, but I don't see nay difference in security between using the multipart message format and using the X-JSON header.
Andy
4/7/2009 12:34 PM
Gravatar Generally speaking the big problem is that it's circumventing "normal" channels for delivering data. On the client any protection mechanisms that might be in place as well as content-filtering and other scanning/scrubbing technologies will be circumvented by passing data through the headers rather than the body.

With a multipart format the core data is still carried in the body and is well-understood by supporting security technology. That's just not true of data being passed around in the headers, especially not custom headers.

Lori MacVittie
4/7/2009 7:18 PM
Gravatar This is really less about Ruby, and more about Prototype (and possibly Rails). Ruby isn't a web framework or a javascript framework.
Adam C. Greenfield
4/8/2009 1:43 AM
Gravatar @Adam

While you're technically correct, the dismissal of the "seriousness" of this technique by the Ruby developers quoted is a large part of the reason for concern.

When developers ignore or dismiss potential security risks in the name of simplicity or an ingenious hack (which this certainly is, no arguing that) it should raise questions about the effectiveness of secure coding policies and the overall effectiveness of security training for such developers.
Lori MacVittie
4/8/2009 1:04 PM
Gravatar Yea, in your quote I agree that dismissing the issue isn't the way to go. I'm just concerned about generalizing "Ruby developers". I think every language/community has developers that don't follow security best practices or that dismiss security concerns in some cases where that isn't warranted.

I agree that it is every developers responsibility (without regard for language choice) to be conscious and careful about the introduction of security issues created by hacks and workarounds.
Adam C. Greenfield
4/8/2009 1:45 PM
Gravatar @Adam

I see your point and agree that Ruby developers en masse aren't ignoring security risks, just the few involved in the discussion.

I will admit that perhaps my years in the press may have brought out some headline tweaking to garner interest and bring the issue to more people's attention to help educate on the dangers of dismissing such allegedly "trivial" risks.

Lori MacVittie
4/9/2009 1:29 PM
Gravatar So is your concern really a philosophical perspective on the use of headers vs. payload, or is it about F5's products validating the data? Seeing how this is posted on F5's site I'm a little suspicious on whether this post has a sales-slant, or a genuine view on web application development patterns.

Either way, allow me to provide some insight around my blog post that you referenced. First, when I said I was putting together a quick demo, that's exactly what it was -- Code running on my local machine as a way to demonstrate an interaction model. It was a prototype used to explore a concept -- not production code. In a production environment one should avoid this approach given the character length limits anyway. The post simply demonstrates how to use the technique.

If you are concerned about validating data, your beef might be with the Prototype library and it's support of this pattern rather then specific languages (like Ruby and Python), which have nothing to do with where one does data validation.

Designing for security is a much bigger issue then where in the HTTP conversation you're passing data. You can put your JSON anywhere, and a man-in-the-middle attack can still taint it.
Erik
4/9/2009 1:36 PM
Gravatar @Erik

Thank you for providing insight into your post. While that certainly sounds reasonable, far too often developers circumvent security in favor of simplicity, as seems the case with this issue. And I say that fully acknowledging that I have been one of those developers in the past.

As far as my concern now, it's about the security of the application. I am not in sales and while I certainly support the use of web application firewalls (and have since long before I joined F5) I write primarily to educate and make folks aware of a variety of application delivery specific issues, one of which is security.

Your suspicion, however, is understandable.

Lori
Lori MacVittie

Let Me Know What You Think


Please use the form below if you have any comments, questions, or suggestions.

Title:
 
Name:
 
Email: (so we can show your gravatar)
Website:
Comment: Allowed tags: blockquote, a, strong, em, p, u, strike, super, sub, code
 
Please add 2 and 7 and type the answer here:

Blog Stats

Posts:979
Comments:1685
Stories:0
Trackbacks:583
  

Image Galleries

  

Application Delivery

  

Cloud Computing

  

Random

  

Security

  

Chat Catcher

82,243 Members in 102 Countries and Growing!

Join DevCentral Today!

About DevCentral

DevCentral has been a successful, thriving community for many years. We have always strived to bring you the best technical documentation, discussion forums, blogs, media and much more that we can.

So dive in, get familiar with DevCentral. We hope you like it, we hope it makes your job easier, and lets you get that much more power out of the community. To learn more, make sure to check out the Getting Started section. And if you have any problems, or think something could be easier to use, drop us a line to let us know.

Got It !

We've received your comment and transmitted it directly to DevCentral HQ.

Thanks for taking time to let us know what's on your mind. At DevCentral | Community Matters!

Get In Touch With Us

Have questions, suggestions or just want to get something off your chest?

Use our handy form below to Direct Connect with DevCentral Mission Control.

Send Us Feedback       or