Technical Article Ruby developers ignore security risks, claim X-JSON header ‘nothing serious’ Updated 07-Apr-2009 • Originally posted on 07-Apr-2009 by Lori MacVittie F5 article api applications dev devops firewall http http headers icontrol internet json management risk ruby security us waf web web 2.0 web application security 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? 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. 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. 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. 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 this 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. Related posts & articles: I am in your HTTP headers, attacking your application The Web 2.0 API: From collaborating to compromised Would you risk $31,000 for milliseconds of application response time? Stop brute force listing of HTTP OPTIONS with network-side scripting 0 Ratings Log in to rate this content Print Download Favorite Share Comments Comment made 09-Apr-2009 by Lori MacVittie F5 @ErikThank 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 Comment made 08-Apr-2009 by Lori MacVittie F5 @AdamI 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. Comment made 08-Apr-2009 by Lori MacVittie F5 @AdamWhile 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. Comment made 07-Apr-2009 by Lori MacVittie F5 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.