PDA

View Full Version : Advisory for developers using JSON



MindCore
2 Apr 2007, 10:05 AM
I have not looked to see if EXT is vulnerable, but I came across the below advisory that suggests that if not properly implemented, using JSON could lead to applications being hijacked. According to the write-up, every AJAX framework that implements a JSON data transfer is vulnerable except for DWR. Check out the links below for more details:

http://www.fortifysoftware.com/servlet/downloads/public/JavaScript_Hijacking.pdf

http://www.fortifysoftware.com/news-events/releases/2007/2007-04-02.jsp

Belgabor
2 Apr 2007, 11:43 AM
If that claim is valid, Ext is probably vulnerable.
I'm not a JS pro, but I'm usually quick to grasp things and have read a bit about HTML/JS/PHP security. Still after reading the paper twice I fail to understand how an attacker can inject that code into the data transfer.
Edit: as I currently understand it, it's not an injection attack, it's rather something like an "automated" session hijacking method.

jon.whitcraft
2 Apr 2007, 11:47 AM
Even if this is so Ext plugs into the parent library via the different bridges so there for if/when the parent library updated to fix this then ext will be fixed when you use the parent library.

Does that make sense??

Belgabor
2 Apr 2007, 11:56 AM
Yes and no. Part of their recommendations is it to make the 'bare' JSON response non-evalable by adding JS "kill" instructions (comments or prepending 'while(1);'). As Ext evals JSON responses itself, it would need to be fixed.

jon.whitcraft
2 Apr 2007, 12:33 PM
Yes i see how that is true. I'm still not sure on the whole thing but i'm sure Jack can shead some light on it.

jack.slocum
2 Apr 2007, 12:37 PM
If you are moving data that is sensitive to hijacking, you should be operating over SSL anyway. End of problem.

Belgabor
2 Apr 2007, 1:24 PM
Edit: I think I got now how it's supposed to work. It requires that the browser sends the cookies for the site in the script tag's href with it and that those cookies include a valid session id. I don't know if SSL protects against that.

San
2 Apr 2007, 1:53 PM
If you are moving data that is sensitive to hijacking, you should be operating over SSL anyway. End of problem.

In the .pdf they suggest wrapping each JSON response with either comments '/* */' or embedding something non-executable in the beginning like a 'throw' or a 'while(1)' (gmail supposedly uses this) to defeat responses being executed in <script> tags.

The response parser then removes the blocking code and does the standard eval().

I think it would be reasonable for Ext to be friendly to one or more of these approaches.

jay@moduscreate.com
2 Apr 2007, 4:56 PM
I have not looked to see if EXT is vulnerable, but I came across the below advisory that suggests that if not properly implemented, using JSON could lead to applications being hijacked. According to the write-up, every AJAX framework that implements a JSON data transfer is vulnerable except for DWR. Check out the links below for more details:

http://www.fortifysoftware.com/servlet/downloads/public/JavaScript_Hijacking.pdf

http://www.fortifysoftware.com/news-events/releases/2007/2007-04-02.jsp

I'm going to play devil's advocate and say that this is NOT NEWS. JSON is NOT a data transfer mechanism. XHR (XML Http Request) is the data transfer mechanism that javascript uses. Being that this is your first post, i'm going to say that you have NOT done your research and are not fully aware of what JSON (JavaScript Object Notation) actually is.


JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.

JavaScript is inherently insecure by design. Again, not news.

XHR is also very insecure. Hell, anything not using SSL based encryptyion is insecure. Not news. so don't you all go bananas over this.

jay@moduscreate.com
2 Apr 2007, 4:57 PM
If you are moving data that is sensitive to hijacking, you should be operating over SSL anyway. End of problem.

We have a winner!! :)

IBTL?

Belgabor
2 Apr 2007, 6:41 PM
Could somebody please read the paper and confirm for sure that this really isn't an issue if you use SSL? If I understood correctly it is not an injection method, it's more similar to an "automated" session hijacking.

MindCore
2 Apr 2007, 7:25 PM
I'm going to play devil's advocate and say that this is NOT NEWS. JSON is NOT a data transfer mechanism. XHR (XML Http Request) is the data transfer mechanism that javascript uses. Being that this is your first post, i'm going to say that you have NOT done your research and are not fully aware of what JSON (JavaScript Object Notation) actually is.

If you had clearly read my post, the first thing I said was that I did not do any research on the topic nor did I mean that JSON was the data transfer mechanism. I was implying that the data being transferred was JSON. I am fully aware of what JSON is and have used it in several projects. I said that this was an advisory that I came across that MAY HAVE (i.e. "that suggests") security vulnerabilities. Don't read too much into my post. Also, just because this is my first post doesn't mean I lack experience in the subject.

Lastly, back on the topic, I would assume that the EXT team would make some efforts to research the issue and make sure that no precautions need to be made even if SSL is implemented.

Belgabor
2 Apr 2007, 7:33 PM
I currently think it is an issue, even if you use SSL. Depends on how browsers handle https in cross-site script tags in relation to the page containing them being http/https with a different certificate. As I currently don't have a https server avilable, I cannot test.

garyng
2 Apr 2007, 10:06 PM
If you are moving data that is sensitive to hijacking, you should be operating over SSL anyway. End of problem.

Would SSL help in this case ?

My understanding of it is :

user visit a rogue site

this site send a page which contains the wire tapping code THEN load from the JSON url of the target server

since it is nothing but an URL request to the target server as far as the browser is concern, it would get pass all the checking(whether it is SSL doesn't matter as it is still between the browser and the server).

on return, the json data are auto eval() since it is told to be javascript in the tag, thus triggered the wire tapping and send everything over.

I believe the easiest fix is just don't pass around naked JSON(valid javascript) but have it quoted in some form such as what the article mentioned, may be just an extra pair of quote is enough.

jay@moduscreate.com
3 Apr 2007, 4:40 AM
If you had clearly read my post, the first thing I said was that I did not do any research on the topic nor did I mean that JSON was the data transfer mechanism. I was implying that the data being transferred was JSON. I am fully aware of what JSON is and have used it in several projects. I said that this was an advisory that I came across that MAY HAVE (i.e. "that suggests") security vulnerabilities. Don't read too much into my post. Also, just because this is my first post doesn't mean I lack experience in the subject.

Lastly, back on the topic, I would assume that the EXT team would make some efforts to research the issue and make sure that no precautions need to be made even if SSL is implemented.


I apologize if i offended you. But your subect "Advisory for developers using JSON", along w/ the post suggests to me that you're reading the article as being a JSON Specific vulnerability. This is simply not the case. JSON Data is just data. Any javascript data being stored is "clear text" as the case w/ JSON.



According to the write-up, every AJAX framework that implements a JSON data transfer is vulnerable except for DWR. Check out the links below for more details:

Also, I think this stems from the evil eval function. At one point DIGG was using eval for their "Digg Spy" where their script would read an array data set every second and eval it.

The problem is fixed by NOT sending confidential data over an unsecure wire. :)

Belgabor
3 Apr 2007, 5:00 AM
The problem is fixed by NOT sending confidential data over an unsecure wire. :)

Are you sure? The line can be perfectly secure, but in this case the endpoint is compromised.

As I understand it for this case, SSL would be like having a mobile phone with a secure line. This method does not try to tap into the conversation, it pick-pockets your phone and presses redial.

MindCore
3 Apr 2007, 5:37 AM
I apologize if i offended you. But your subect "Advisory for developers using JSON", along w/ the post suggests to me that you're reading the article as being a JSON Specific vulnerability. This is simply not the case. JSON Data is just data. Any javascript data being stored is "clear text" as the case w/ JSON.


Also, I think this stems from the evil eval function. At one point DIGG was using eval for their "Digg Spy" where their script would read an array data set every second and eval it.

The problem is fixed by NOT sending confidential data over an unsecure wire. :)


Apology accepted... I too must apologize as I probably came across a bit abrupt and after rereading my post made it seem that this was an urgent issue. However, it just needs further research. I am in agreement with Belgabor on the issue. I don't think it matters if your connection is secure or not (i.e. SSL). It is an automated attack that examines cookie information for valid sessions and exploits it. So, for example, if you use an AJAX application then surf to a malicious site, it can, as Belgabor puts it, "pick pocket" session information. The article suggests that AJAX frameworks should prevent this session information from being reused by another client. So, as everyone has been saying, this is not new news as by design we all know Javascript is not secure. It is just a suggestion to prevent a specific type of attack.

dewd
3 Apr 2007, 5:55 AM
I am creating my own wrapper for Ext programming, and to solve this issue I am going to re-check the session_id by capturing the session_id in the cookie and sending it in the JSON request, but I am also going to comment out the JSON data just so it won't be available in simple <script> blocks.

OK, my code sucks, but it's a work in progress for me and I am still learning my way in JavaScript and Ext. :-)

Here it is:

x: function(u, fn){
var c = new Ext.data.Connection;
var session_id = new Ext.state.CookieProvider().get('session_id');
c.on('requestcomplete', function(h, b){
var s = b['responseText'];
if (s.match(/^\s*\/\*/)){
s = s.replace(/^\s*\/\*/, '').replace(/\*\/\s*$/, '');
}
fn(eval(s));
});
c.request({url: u}, {session_id: session_id});
}


I'll use it for most of my JSON requests and it's paranoid enough, as I learned in
this GWT security discussion yesterday:
http://groups.google.com/group/Google-Web-Toolkit/web/security-for-gwt-applications

I think you should read the above as well because it explains all the common threats
to your web applications in a very clear language. (Thanks Google!) :-)

Cheers,
Joao

jay@moduscreate.com
3 Apr 2007, 11:55 AM
Are you sure? The line can be perfectly secure, but in this case the endpoint is compromised.

As I understand it for this case, SSL would be like having a mobile phone with a secure line. This method does not try to tap into the conversation, it pick-pockets your phone and presses redial.

That's the case for every form of transmission. Data, voice, analog, morse code ;).

SSL Makes it really hard for snoopers to read data over the wire, which is what i'm gathering this article is aimed towards.

They are targeting JavaScript generated data transmission, but this is nothing that is shocking to me. I mean, before JS was used for Ajax stuff, HTTP sessions were used w/ cookies. again, unsecure. So I'm not surprised at all.

jay@moduscreate.com
3 Apr 2007, 12:03 PM
The article suggests that AJAX frameworks should prevent this session information from being reused by another client. So, as everyone has been saying, this is not new news as by design we all know Javascript is not secure. It is just a suggestion to prevent a specific type of attack.

The crux of the problem is javascript all together. But we all love it for it's convenience. Why would session information from one site be available to another? That's retarded. I wonder why they didn't put in restrictions like the XHR connection to one site restriction... :-/

Belgabor
3 Apr 2007, 12:18 PM
SSL Makes it really hard for snoopers to read data over the wire, which is what i'm gathering this article is aimed towards.

No, it's not. The point is that an attacker's website (where the victim has to be lured to) poses as the legitimate application and circumvents the on-host policy with a script tag. Normally this doesn't work as the JSON response is a pure datablock that, if scripttagged in, runs into empty space. But if you overwrite central JS functions, like the Array constructor, you can capture the assignment process that nevertheless takes place and send that to an on-(attacker)site capture script.


The crux of the problem is javascript all together. But we all love it for it's convenience. Why would session information from one site be available to another? That's retarded. I wonder why they didn't put in restrictions like the XHR connection to one site restriction... :-/

According to what I've read, the cookie spec says exactly that, but the browsers don't implement it that way as lots of sites would break. (The page also said that it's more likely that the cookie spec would be changed to accommodate Web 2.0 and the ad schemes that use it...)

chubbard
3 Apr 2007, 1:30 PM
This is a cross site forgery request (CSFR), and you CAN'T prevent them by just using SSL. No one is snooping the data off the wire, and that's why SSL doesn't help. The hijacking occurs after the decryption of the data. They are snooping in javascript by overwriting the Array.prototype object's default functions.

Let's say you have logged into yourbank.com website, and that website has sent you a cookie to identify your browser session as a user. Then you got visit a malicious website in another tab.

The bad website sends you a page like this:

<script src="js/overwrite-array.js"></script>
<script src="https://yourbank.com/account-ledger/json"></script>

The first script changes the Array object and overwrites all the functions with my hijacking functions. The second feteches your accound ledger in a JSON request that yourbank.com implemented. The browser will eval the the results from the yourbank.com, and viola I've hijacked all your data.

If your JSON webservice requires clients place the session ID in the URL as a parameter to the request then the above won't work. The malicous site can't forge the request because it can't guess the session ID. And, the malicious site can't read the session ID from another domain so you're ok.

There are other ways of preventing CSFR. Essentially placing the session ID in the request is just putting something into the request the malicious user can't guess thereby authenticating the user making the request. Notice that if I had made the URL include the bank account number then it would also be hard for someone to forge. So a URL like:

https://yourbank.com/123-45-123467/account-ledger/json

Would also thwart forgery assuming the account number is kept private just like the session ID. Both sending the account number or session ID are subject to snooping if you send them in clear text (ie http). You most definitely wouldn't want to send this in clear text! But, this technique does prevent CSFR. If you're working with a clear text JSON request you'll have to do something else. Hacks like the throw or while(1); are easily circumventable. GMail's solution while it might help stem the damage it doesn't prevent a snooper from getting your email.

Again I want to make sure everyone realizes using SSL doesn't fix this problem.

jay@moduscreate.com
3 Apr 2007, 1:47 PM
^^^ So you're saying that it's possible to read data from one tab to another? Doesn't that violate some type of fundamental rule in the way the browsers are supposed to work? I mean each "tab" should emulate another browser instance.


Also, i still fail to see how this is a JSON Specific problem. I think the central issue is eval.

garyng
3 Apr 2007, 4:59 PM
^^^ So you're saying that it's possible to read data from one tab to another? Doesn't that violate some type of fundamental rule in the way the browsers are supposed to work? I mean each "tab" should emulate another browser instance.


Also, i still fail to see how this is a JSON Specific problem. I think the central issue is eval.

It is not read data from one tab to another. It is in the same tab/window. The central issue is indeed eval() but naked JSON(which is valid javascript source) is "auto-eval()" when being put into the following script :

<script src="http://your_host/naked_json_return"></script>

Then, by overriding the Object setter(the analogy of key logger), everything run is captured.

Note that the cookie info are not leaked, only the returned json data.

It is quite easy to prevent this, just don't return valid javascript result, returned "quoted" JSON instead.

Having the json return url in the following form also help:

http://your_host/naked_json_return/sessionid
http://your_host/naked_json_return?sessionid=sessiond

Of course, we are assuming these are sent over ssl to prevent leaking of sessionid(which also leaks even in cookie form).

chubbard
3 Apr 2007, 6:15 PM
There are several key factors in this attack. It's not just eval alone that's the problem. And yes JSON is a key factor as well because JSON can be eval'ed directly by the script tag. If the web service sent something that can't be eval'ed directly then it wouldn't be a problem.

It's not reading data from the tab. What it's doing is sending a request to a domain that you've authenticated in another tab. While the actual data isn't shared the cookies ARE shared across tabs and windows. For proof of this fact open up a second tab to this forum. Notice that you're logged in on that second tab! Make a post from the 2nd tab. It will work, and you won't have to log in. The 2nd tab knows it's you without having to authenticate. How does it know without authenticating again? Well that's because the cookies are shared so you're session ID is shared across those two tabs. That's why you didn't have to reauthenticate in the 2nd tab to that domain.

Cookies are paired with the domain in which they originate, and browsers send those cookies no matter which tab/window they came from. So the session ID in the other tab acquired is sent in the request from the second tab. So if a 3rd party can guess what the URL should be for sensitive data it can forge the request to get that data because you've authenticated in another tab.

When the browser reads a script tag it evals the response it receives from the server. Since JSON is nothing more than javascript it will eval it just like it does with normal scripts.

Belgabor
3 Apr 2007, 7:11 PM
^^^ So you're saying that it's possible to read data from one tab to another? Doesn't that violate some type of fundamental rule in the way the browsers are supposed to work? I mean each "tab" should emulate another browser instance.

Also, i still fail to see how this is a JSON Specific problem. I think the central issue is eval.


There are several key factors in this attack. It's not just eval alone that's the problem. And yes JSON is a key factor as well because JSON can be eval'ed directly by the script tag. If the web service sent something that can't be eval'ed directly then it wouldn't be a problem.

Personally I think only JSON is the problem, not eval (at least not as the function you write it in your JS code) as you cannot circumvent the attack by using a JS JSON decoder that doesn't use eval.




If you're working with a clear text JSON request you'll have to do something else. Hacks like the throw or while(1); are easily circumventable. GMail's solution while it might help stem the damage it doesn't prevent a snooper from getting your email.

How do you think this is circumventable? The attack relies on the executability of the response pulled in via a script tag, which is not given in that case.


chubbard has given a lot of good explanation, so there is just one last thing I want to clarify (he basically said it, but I think it's important that everybody understands).

Cookies are only sent to the domain that set them, this makes simply stealing them impossible. The problem is that the browser doesn't choose this domain from the page you open in your browser, it uses the domain in the called url. So a script tag is pulled in with the cookies that belong to the domain that hosts the called script. And that's the vulnerability. It's like stealing a mobile phone that's switched on, you don't know the pin, but you can still can use it to make phone calls on the owner's bill.

JeffHowden
3 Apr 2007, 7:26 PM
For those getting caught up in the mention of "tabs" with the descriptions of this vulnerability, note that it doesn't matter if it's tabs or windows. All that matters is that you're logged in to site A (the good site) and view site B (the bad site) while still logged into site A. If the paths to sensitive data via JSON is guessable and not unique for every user, site B can reference that path in a <script> tag. If the path returns naked JSON (ie, not quoted, commented, etc.) the browser will treat that response as a valid JavaScript file and parse the contents into memory. Depending on the way the JSON is structured, they may not even need to mess with internal JavaScript objects to be able to access the info contained in the JSON.

That said, I'm having a very difficult time getting an example that illustrates this vulnerability to work in either IE7 or FF2. I have the following HTML:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>Test JSON Vulnerability</title>
<script src="http://ext.vosandhowden.com/test.js"></script>
</head>
<body></body>
</html>

Then, the JSON at the URL referenced in the HTML above is:


{
'totalCount': 100
, 'data': [
{ 'foo': 'bar', 'id': 1 }
, { 'goo': 'tar', 'id': 2 }
, { 'boo': 'far', 'id': 3 }
]
}

The browser absolutely refuses to parse that file as a JavaScript file. It just throws an error.

In IE7:


A Runtime Error has occurred.
Do you wish to Debug?

Line: 5
Error: Expected ';'

In FF2:


invalid label

Belgabor
3 Apr 2007, 8:24 PM
Jeff, I think the problem might be that if you add the capture code, the error might be thrown too late, ie the capture is already done then. I haven't checked this though.
Also I think it was first described with an array, although objects were reported to work as well.

JeffHowden
3 Apr 2007, 11:47 PM
Indeed, using an array as the response, it loads without issue.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>Test JSON Vulnerability</title>
<script src="http://ext.vosandhowden.com/test2.js"></script>
</head>
<body></body>
</html>

It does not work with objects though, at least not in my test case.

jay@moduscreate.com
4 Apr 2007, 4:04 AM
Personally I think only JSON is the problem, not eval (at least not as the function you write it in your JS code) as you cannot circumvent the attack by using a JS JSON decoder that doesn't use eval.

I don't see how this is correct. The code needs to be eval'ed in one form or another. JSON is a way of writing data. Tons of sites return (to the browser) raw array data, which again needs to be eval'ed. How do you turn the string data returned by an XHR to javascript - other than using eval? You could use a parser but i would imagine that would be extremely slow.

chubbard
4 Apr 2007, 7:29 AM
Personally I think only JSON is the problem, not eval (at least not as the function you write it in your JS code) as you cannot circumvent the attack by using a JS JSON decoder that doesn't use eval.

How do you think this is circumventable? The attack relies on the executability of the response pulled in via a script tag, which is not given in that case.



I think I might have mispoke on that one. :"> For this type of attack it would prevent it and I don't think it's circumventable. But, I wonder about other CSRF attacks...

At first I thought well if I was trying to hack someone's site, and I knew that they were using JSON in some area, then it's highly likely I would also know they send non-eval'able JSON with comments, while(1), or a throw clause. Then I could strip that off just as they stripped it off when they do XHR. So those might prevent this attack, but I'm not sure this is a good counter measures in general.

I think essentially it boils down to an authentication problem in the cookie system. Because browsers are required to send the cookies back to the domain it allows the forgery to happen. So sending the cookie in the request is like authenticating again with the server but not through cookies per se. It's redundant to send the session ID in the request, but you have to to truely seperate out when someone is a legitimate request vs. a forged request.

Charlie

chubbard
4 Apr 2007, 7:32 AM
Then, the JSON at the URL referenced in the HTML above is:



{
'totalCount': 100,
'data': [
{ 'foo': 'bar', 'id': 1 },
{ 'goo': 'tar', 'id': 2 },
{ 'boo': 'far', 'id': 3 }
]
}




Don't you just need to terminate the object definition with a ';'?



{
'totalCount': 100,
'data': [
{ 'foo': 'bar', 'id': 1 },
{ 'goo': 'tar', 'id': 2 },
{ 'boo': 'far', 'id': 3 }
]
};

JeffHowden
4 Apr 2007, 7:43 AM
I think I might have mispoke on that one. :"> For this type of attack it would prevent it and I don't think it's circumventable. But, I wonder about other CSRF attacks...

At first I thought well if I was trying to hack someone's site, and I knew that they were using JSON in some area, then it's highly likely I would also know they send non-eval'able JSON with comments, while(1), or a throw clause. Then I could strip that off just as they stripped it off when they do XHR. So those might prevent this attack, but I'm not sure this is a good counter measures in general.

I think essentially it boils down to an authentication problem in the cookie system. Because browsers are required to send the cookies back to the domain it allows the forgery to happen. So sending the cookie in the request is like authenticating again with the server but not through cookies per se. It's redundant to send the session ID in the request, but you have to to truely seperate out when someone is a legitimate request vs. a forged request.

Charlie
Nope, I tried it with and without and it yielded the same results.

timb
5 Apr 2007, 10:23 AM
I found a nice blog that puts this into perspective:
http://bob.pythonmac.org/archives/2007/04/05/fortify-javascript-hijacking-fud/

Quick quote:

The simplest solution is to just change the JSON RFC to include a strong recommendation that only objects should be allowed as an envelope.

I think most of us do this anyway.

heidtmare
5 Apr 2007, 10:34 AM
wow, that cleared it up. Guess I never had anything to worry about since I only work with objects.

Belgabor
5 Apr 2007, 11:50 AM
I don't see how this is correct. The code needs to be eval'ed in one form or another. JSON is a way of writing data. Tons of sites return (to the browser) raw array data, which again needs to be eval'ed. How do you turn the string data returned by an XHR to javascript - other than using eval? You could use a parser but i would imagine that would be extremely slow.

I thought of the json JS lib available from json.org. It also uses eval, but does a bit more to protect you from harmful code in the response. Alas by design it does not (and cannot) protect from this attack.


At first I thought well if I was trying to hack someone's site, and I knew that they were using JSON in some area, then it's highly likely I would also know they send non-eval'able JSON with comments, while(1), or a throw clause. Then I could strip that off just as they stripped it off when they do XHR. So those might prevent this attack, but I'm not sure this is a good counter measures in general.

That may sound logical at first glance, but how should he (the attacker) strip it off? He has to use a script tag, which makes the raw result of the query inaccessible to him.

timb, thanks for the link. I was also skeptical at first (as you can read from my first response) and the link proved my intuition true :p
So to reevaluate my first response: As far as I know all internal AJAX transfers in Ext use objects, so Ext in itself is not vulnerable. :D

vtswingkid
5 Apr 2007, 12:52 PM
I have not tested this. But it seems to me the response could be anything besides json. And it could still be stolen.

Good site A with credentials(cookies, session) verified returns random deciferable data.

Bad site B loads javascript that creates an htmlrequest with a correctly guessed url reussing the shared credentials (cookies, session). It can store the response as a string if it wants. voila.

As mentioned earlier additional credentials need to be posted -assumes ssl.

Maybe I am wrong, as I have said I haven't tried it. Great topic though...gets the juices flowing

HoldemJacket
5 Apr 2007, 2:15 PM
Good site A with credentials(cookies, session) verified returns random deciferable data.

Bad site B loads javascript that creates an htmlrequest with a correctly guessed url reussing the shared credentials (cookies, session). It can store the response as a string if it wants. voila.


The problem with this is that site B does not have access to site A's cookies. Any request that site B's script makes will not include site A's cookies. The script tag was one of the keys to this attack. Since the browser is making the request for the script file AND the script file is on site A's domain, the browser sends the cookies along. Site B still has no idea what is in the cookies, that's why it has to use another script to "steal" the info in the script tag.

JeffHowden
5 Apr 2007, 3:28 PM
I have not tested this. But it seems to me the response could be anything besides json. And it could still be stolen.

Good site A with credentials(cookies, session) verified returns random deciferable data.

Bad site B loads javascript that creates an htmlrequest with a correctly guessed url reussing the shared credentials (cookies, session). It can store the response as a string if it wants. voila.

As mentioned earlier additional credentials need to be posted -assumes ssl.

Maybe I am wrong, as I have said I haven't tried it. Great topic though...gets the juices flowing

The flaw in that breakdown is that Bad site B cannot gain access to the contents of the JS file returned by Good site A in the <script> tag call. Remember, it's not Bad site B actually making the request, it's the user that happens to be visiting both Good site A and Bad site B while their session on Good site A is still intact. Additionally, this only works if the path to the JSON data on Good site A doesn't contain any unique data. If it does, Bad site B would have no way of knowing what that unique data is specifically for their current visitor and could not forge a request via the script tag.

Bottom line, this is a bunk vulnerability dreamed up by a "security" company who's looking to issue a press release to build some hype, blew the issue way out of proportion, attributed it to AJAX (for the buzzword factor), made claims that are patently false (like object literals being vulnerable when it's actually only array primitives and even then *only* in Firefox), and hoped to not get caught with their pants down (far too late for that).

Sorry Fortify, in the words of The Donald, you suck.

The "solution" for all the rest of us?


Make sure our URLs for JSON data requests are always unique per user.
Never use an array primitive as your response or worded another way, always use an object literal for your response.

JasonMichael
5 Apr 2007, 7:16 PM
Haha, I love this final word on this (4 pages later)! I skimmed page 1, page 3, and finally read this one. I expected this would be the verdict. :) I tip my hat to all of you though that made this such a great read.

Juanito
26 Apr 2007, 5:53 AM
The "solution" for all the rest of us?


Make sure our URLs for JSON data requests are always unique per user.
Never use an array primitive as your response or worded another way, always use an object literal for your response.


For anybody using TreeLoader, beware that its default behavior is to load an array, which is susceptible to this attack. The solution is to extend TreeLoader and modify processResponse to accept an object since objects are not susceptible to this attack.

@Jeff: The reason only arrays cause the problem is that an object literal is not a valid js statement, it causes a syntax error when evaled. However, if you put parentheses around it (like we do when we eval json responses), it does become a valid statement and could be exploited by overwriting Object's constructor. However, an array literal is a valid statement (which will cause the overriden Array constructor to be called), try it in firebug's console.

Here's my fix to avoid this potential issue: Please forgive me if I messed up some syntax for extending, I use a different scheme for inheritance (http://www.uselesspickles.com/blog/the-class-library/)



function XTreeLoader(cfg) {
this.superClass.call(this, cfg);
}

Ext.extend( XTreeLoader, Ext.tree.TreeLoader, {

// Modified version of processResponse, server code must be updated to wrap array with
// an object whose 'nodes' property, is the array to be loaded
processResponse: function(response, node, callback){
var json = response.responseText;
try {
var o = eval("("+json+")");

/****** START MODIFIED CODE **************/
var o = o.nodes; // Returned array is wrapped by an object containing a nodes property
/***** END MODIFIED CODE ******************/
for(var i = 0, len = o.length; i < len; i++){
var n = this.createNode(o[i]);
if(n){
node.appendChild(n);
}
}
if(typeof callback == "function"){
callback(this, node);
}
}catch(e){
this.handleFailure(response);
}
},
});



Note: This could be done in a number of other ways by adding any non-evalable code in the json response and stripping it out before evaling the result.

Also, I've gone through that document from fortify and believe I understand it fairly well. Anyone is welcome to pm me if they would like to further understand this vulnerability.

--Juan

padawan
15 May 2007, 9:17 PM
Hi all,

and many thanks for this informative thread.

Also double cookie confirmation, (a description of the idea (http://jpsykes.com/47/practical-csrf-and-json-security)) seems to be an effective way to reduce possibilites for various kinds of CSRF (and JSON) exploits.

trbot
27 Jun 2007, 7:47 AM
Totally trivial, but I think all of you mean overriding, when speaking of altering function definitions that have the same signature.

Overloading -> different signature, can be called along-side original function.
Overriding -> same signature, lower down the hierarchical chain, replaces the original function.

This exploit still sounds like a bit of a long-shot. :P

potdarko
3 Jul 2007, 10:38 AM
interesting post (with a basic plain example) :

Security on AIR: Local file access through JavaScript (http://seclists.org/bugtraq/2007/Jul/0018.html)
~o)

haibijon
3 Jul 2007, 10:02 PM
@potdarko There have already been several blog posts talking about the 'insecurity' of AIR being able to access files, sockets etc. But when it comes down to it, the reality is that there's nothing (aside from fs permissions) keeping a malicious application (written using AIR, java, c, c++, whatever) from rewriting DLL's, or a whole replacing a whole application, or even whiping system files for that matter.

With AIR you're building desktop application. Frankly I think adobe's warning about the application's access is better than most installers which don't warn you about possible security risks.

perler
8 Feb 2008, 1:36 AM
sorry to bring this up again,

but I think I found a simple solution:

ExtJS sends a HTTP-header named "X-Requested-With". If this is set to"XMLHttpRequest" I send the JSON otherwise I send an error or something else. A <script src> call cannot include http-headers to the request. Only XHR can do that, but the same origin policy prevents the request to be sent.

Comments on that?

It could me implemented by using some Apache config options or PHP,Java,Perl can handle it.

Edit:
I found this document http://www.webappsec.org/lists/websecurity/archive/2006-07/msg00069.html which describes, that one cannot rely on the http headers. They can easily be changed by malicous flash movies.

But you can add the session to the header in every XHR request you fire in ExtJS. And check whether this is correct or not. Guess this might help, because the malicous flash file cannot know the session id, if it resides in a different server

advisoryworldmwilson
18 Dec 2008, 1:06 PM
Does anyone know of a good open-source security vulnerability scanning tool that will work with EXTJS? Thank you.