0

(I already know that ajax calls has to be from the same origin , and already read the relevant answers)

But I have a problem understanding something :

Facebook (among others) use the for(;;) || while(1) thing in their json responses :

enter image description here

And - obviously - if I want to use the data I have to remove the for(;;) string and then parse it myself.

I was also told (by @esailija) that :

You can't remove the for loop unless you are from same origin that's the point

Ok great - this is because of the same origin policy.

But I ask this :

Lets say John is doing this on his site (john.com):

 bla bla...
   <script src="facebook.com/ajax/recent" type="text/javascript"></script>
 bla bla...

Notice its the same url as facebook's ( my left most red arrow) -

Assumption

  • If he get the response via <scrip>...</script> and the response was without for(;;) , - he still can't do nothing with {"__ar:1,....} ! it will has to be padded (like jsonp) with myCallBack({"__ar:1,....});

I mean : It's just like this :

var a=1;

{"__ar:1,....}  <--- john can't do nothing with this.

var b=1;

Question :

What am I missing and does my assumptions are correct ?

Community
  • 1
  • 1
Royi Namir
  • 131,490
  • 121
  • 408
  • 714

3 Answers3

2

The problem at the time was that it was not safe to have a noop-looking array literal. E.g. executing code like this:

[1,2,3]

Would actually call the array constructor with those values. Which will be far from harmless as the following example shows:

<script>
Array = function() {
     //Steal the values etc
};
</script>
<script src="facebook.com/yourtimeline.json"></script>
//above has code like [{profile_id}, {},...] which calls the array constructor
//with those values and I have access to them.

If you visited my page on older browser (and I do mean old, as in firefox 2) while logged in on facebook, I could get your data silently in the array constructor if there was no for(;;). But because there is, my page will just loop indefinitely.

Esailija
  • 130,716
  • 22
  • 250
  • 308
1

If he got the response and (as you said) it didn't have for(;;); at the beginning, then it would be a valid segment of JavaScript code (an object initializer) whose result wasn't stored anywhere. It would run harmlessly. But people protecting their JSON feeds this way don't want them to run harmlessly when being misused like this, so they add this intentional pollution at the beginning so that attempting to misuse them is painful, because it triggers an endless loop.

The typical way to consume a feed with that kind of intentional-pollution at the beginning relies on being on the same origin (or at least, an origin allowed by their CORS policy): You load the feed via ajax as text, strip off the leading for(;;);, and then parse the remainder as JSON.

T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
1

Your first assumption is wrong, but the second is right.

Eventhough you can't do an AJAX request to a different origin, you can load a script from a different origin. This is how JSONP does a request to a different origin.

The JSONP format is different from JSON just for this reason. It's JSON wrapped in a function call, so that you can use the response. Just as you assume, a JSON response is useless when loaded as a script, as it will just be evaluated and then discarded.

Edit

To keep up with the edits; the first assumption (that the request wouldn't work at all) was removed from the question.

Community
  • 1
  • 1
Guffa
  • 640,220
  • 96
  • 678
  • 956