
Why does Google append while(1); in front of their JSON responses? - i386
http://stackoverflow.com/questions/2669690/why-does-google-append-while1-in-front-of-their-json-responses
======
mmahemoff
This works because the browser will run any third-party script, but it won't
expose the raw string constituting the script.

So a malicious website can't steal that content by putting the URL in a
script. It will never get to see what's in the script and only a same-domain
script could parse the whole contents, by making a XHR call, and strip out the
"while 1;" part. In contrast, a regular JSONP string is specifically designed
for the third party to read it (by including code to call a callback
function).

A lot of people still don't realise you shouldn't be serving private data as
JSONP. Thankfully, CORS lets modern browsers go cross-browser safely, even
with private data if things are configured right.

~~~
facorreia
"Thankfully, CORS lets modern browsers go cross-browser safely, even with
private data if things are configured right."

Would you clarify or add some pointers to where we can learn about CORS
benefits for private data? CSRF is a huge but often underestimated issue.

~~~
mmahemoff
Actually as yoghur points out, CORS doesn't protect against CSRF. A token must
be passed for any privileged calls.

That said, a benefit of CORS is the ability to do non-GET methods. So it's
safer in the sense of HTTP idempotence, ie you can change server state safely,
using POSTs, DELETEs, and so on. You'd still need to pass a token, however.

(Of course I meant cross-domain, not cross-browser :).

------
kwamenum86
Actually this prevents XSSI (cross-site script inclusion) not XSRF (cross-site
request forgery).

XSRF vulnerabilities allow an attacker to issue web requests on a user's
behalf; oftentimes though people only call it a vulnerability when you can
issue a request that changes some state. And XSRF is usually prevented by
including a hard to guess token with the request that is tied to the user and
allows you to determine whether the request was generated by an authorized
party. Please don't try to prevent XSRF by using while(1) :)

------
seag
You don't append in front, you prepend

~~~
knowtheory
I'm a bit perplex why you've chosen to pedantize this particular word choice
since "prepend" itself is a portmanteau derived by mashing "pre" and "append"
together.

Perhaps the trio of "affix", "prefix" and "suffix" might be more useful, since
there is no "postpend" or "suppend" to accompany "append" and "prepend".

Regardless, the Google ngram chart of these various words is pretty
interesting:
[http://books.google.com/ngrams/graph?content=prepend%2Cappen...](http://books.google.com/ngrams/graph?content=prepend%2Cappend%2Cprefix%2Caffix%2Csuffix&year_start=1800&year_end=2000&corpus=15&smoothing=3&share=)

~~~
bradleyjg
I assume the neologism was intentional?

[http://books.google.com/ngrams/graph?content=pedantize&y...](http://books.google.com/ngrams/graph?content=pedantize&year_start=1800&year_end=2000&corpus=15&smoothing=3&share=)

------
patorjk
If you look at the gmail ajax calls, you'll also see they sometimes put a
number in front of their data. Example:

3

[1, 2, 3, 0]

If you execute that in your JS console, it'll return undefined, which threw me
for a loop a couple days ago when I saw it. I ended up having it ask on
StackOverflow too and it's because JavaScript will interpret it as a property
look up on that number object (it will evaluate to 3[0], which evaluates to
undefined).

~~~
Hello71
Something comma operator something.

------
nodesocket
This doesn't protect again using an <img> tag to accomplish the same thing
correct? Assume a malicious user wanted to delete something and the URI was
formatted like: <http://mydomain.com/delete/some-id-here>. Then assuming the
user is logged in, a simple <img src="<http://www.mydomain.com/delete/some-id-
here> /> on a third party site would execute the request successfully correct?

~~~
hendi_
Yes. This is why you never perform any actions which change something over
GET. Use POST (or PUT or DELETE) for them.

~~~
nostrademons
This is one of the reasons why you never perform any actions which change
something over GET. The main reason is so your site doesn't get deleted when
the Googlebot visits. (Or more generally, so that web crawlers and other
robots don't accidentally mutate the site.)

Using POST is not sufficient; you also need to include an XSRF token that only
the requesting page knows. It's very possible to send a POST to a third-party
site with about one line of Javascript. (In the relatively early days of
Reddit, I wrote a page that upvoted itself by having a JS handler in an
invisible iframe resubmit the same link over again, using the visitor's login
credentials. At the time, submitting the same link twice on Reddit counted as
an upvote, and so merely visiting the page would upvote the link.)

~~~
hendi_
You're right, I only focused on that one single reason for my post since I was
in a hurry.

Security issues are obviously more complex than one-line explanations. Thank
you for your more elaborate reply!

------
hayksaakian
> closed

Good 'ol stackoverflow

~~~
_pmf_
Wikipedia has shown us what ridiculous bureaucracy does to a community; it's
sad that Stackoverflow has been turned into a utterly useless site despite the
lessons that could have been learned from Wikipedia.

~~~
T-hawk
It's the Iron Law of Bureaucracy, coined in that form by Jerry Pournelle.
<http://www.jerrypournelle.com/reports/jerryp/iron.html>

Every organization becomes controlled by those who serve the organization
itself, as opposed to those who perform the actual goal or service of the
organization. Schools are controlled by administrators, not the teachers.
Wikipedia and other community-sourced internet sites are run by those who
desired to acquire power over Wikipedia, not by those who desire to contribute
content.

------
sil3ntmac
Wait.. so any JSON API that doesn't do this is technically vulnerable to CSRF?
Mind blown.

~~~
apendleton
This method only works for HTTP GETs, and can't get around requirements to
present CSRF tokens with the request. This is one of several possible
strategies for guarding against CSRF.

~~~
ville
Wouldn't also using a custom HTTP header instead of cookies for passing a
session identifier prevent this attack? A script tag can not set headers,
right?

~~~
thezilch
Not quite, thanks to Flash.

[http://lists.webappsec.org/pipermail/websecurity_lists.webap...](http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2011-February/007533.html)

Rails and Django patches/recommendations on the issue:
[http://weblog.rubyonrails.org/2011/2/8/csrf-protection-
bypas...](http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-
ruby-on-rails/)
[https://docs.djangoproject.com/en/1.2/releases/1.2.5/#csrf-e...](https://docs.djangoproject.com/en/1.2/releases/1.2.5/#csrf-
exception-for-ajax-requests)

~~~
deliminator
Correct me if I'm wrong, but does this not merely allow an attacker to cause
the browser to make requests with custom headers? That is, it does not allow
the attacker to gain the CSRF token, and if the CSRF token is not known to the
attacker, he would still not be able to make API requests.

------
twistedpair
This can really be broken because you can redefine the numeric constructor of
1 to return false and thus get around the while(1). However, if for(;;) was
used, then you cannot get around it. ;)

~~~
aleem
I'm curious--how would you redefine it? Could you share a code snippet or
reference?

------
ahrjay
Source maps recommend a similar technique to mitigate against XSSI attacks by
prepending ")]}" to your source map
[http://www.html5rocks.com/en/tutorials/developertools/source...](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-
xssi)

------
swah
I think this why Flask only allows top-level objects, not arrays. Am I right?

(<http://flask.pocoo.org/docs/security/#json-security>)

------
boop0x6
I wonder how many times this vulnerability has been exploited before they've
implemented this hack.

~~~
dpup
If I remember correctly, it was first discovered pretty soon after a version
of Gecko was introduced with support for setters/getters, and Gecko had
minority market share at that time.

[http://jeremiahgrossman.blogspot.com/2006/01/advanced-web-
at...](http://jeremiahgrossman.blogspot.com/2006/01/advanced-web-attack-
techniques-using.html)

------
homakov
it was known like 4 years ago. I prefer to just use / _

------
martinced
That such hacks are used as security measures makes me think that we've heard
far from the last JavaScript exploit.

Now I find that workaround sweet: but it's still a total kludge and that such
kludges are used just shows how poorly security has been conceived from the
ground up in browsers / JavaScript.

~~~
tptacek
Along the same lines, see how you feel about browser security in general after
reading: <http://lcamtuf.coredump.cx/postxss/>

~~~
a3_nm
There's a great book about browser security by the same author: _The Tangled
Web_
<[http://lcamtuf.coredump.cx/tangled/>](http://lcamtuf.coredump.cx/tangled/>);

