DEV Community

loading...

Why Facebook's api starts with a for loop

Antony Garand on November 13, 2018

If you ever inspected your requests to big company's API's in the browser, you might have noticed some weird javascript before the JSON itself: F...
Collapse
ben profile image
Ben Halpern

This is incredibly illuminating. Thank you so much for this Antony!

Collapse
raphipsp profile image
raphipsp

Replace var x with an html script tag?
But how?

Collapse
antogarand profile image
Antony Garand Author

In your webpage, you would do the following:

<script>
function Array(){
    alert('You created an array!');
}
</script>
<script src="https://gmail.com/messages"></script>

This way you overload the constructor before loading the messages themselves.

Collapse
raphipsp profile image
raphipsp

Ah ok, I see.
I think the way it is written in the article is confusing. It should instead say "override the Array constructor before loading external scripts"

Thread Thread
antogarand profile image
Antony Garand Author

Thanks for the feedback, updated the post so it's more clear

Thread Thread
raphipsp profile image
raphipsp

Wow you're fast!

Collapse
snorfalorpagus profile image
Joshua Arnott • Edited

I can see how adding an infinite for-loop at the start of the JSON response would prevent it from being executed as JavaScript. How does the original site access the data? Does it need to use a function to discard the first X bytes of every response before loading the JSON? Or is there something I'm missing?

Collapse
antogarand profile image
Antony Garand Author

This is exactly it!

As they load the string version of the JSON, they can remove their JS breaking mechanism before parsing it

Collapse
cben profile image
Beni Cherniavsky-Paskin

Is this all only to protect people that misuse eval() to parse JSON? JSON.parse() has never been affected by any of this, right?

Hmm, the article gives example of malicious site loading the JSON API directly with a script tag: <script src="https://gmail.com/messages"></script>.
So here's where I'm confused:

  1. Why would a differed site have authentication to get answers from the API using a script tag?
  2. If it works with a script tag and hacks to extract data from evaluating JSON as JS, why won't it work anyway with an AJAX request, parsing the result however you want?

Is this because script tags are historically lax about same-origin policies? I knew evil.example.com can include a script tag for gmail.com, but does that also give such request access to gmail.com cookies?!?

Collapse
lexlohr profile image
Alex Lohr
  1. a script tag will basically send the same request that would be sent if the URL itself was loaded in the browser - if the browser has cookies saved for the URL, they will be sent and thus authentication cookies can successfully be validated.
  2. because AJAX requests are discarded by the browser unless the correct Cross Origin Resource Sharing (CORS) headers are set on the server, so you won't get the result.

While it is absolutely possible to implement a strict security layer on an API server, this will also increase the CPU/memory/bandwidth requirements. If you have a really big service such as gmail, you'd rather do as much security as possible on the front-end level.

Collapse
miffpengi profile image
Miff

I'm really wondering how any of these attack techniques would fare against simpler CSRF techniques like double-submitted cookies.

Other stupid ways that seem like they could mitigate this would be to just make all the JSON endpoints require a POST, or to use a different method of encoding data that can't be interpreted as valid Javascript at all (XML?)

Collapse
nathan815 profile image
Nathan Johnson

Making them all POST wouldn't be semantic (POST means you're changing something on the server). JSON is the standard API data format now, and it's much better than XML in my opinion.

The ultimate way to prevent these attacks is to not allow user submitted input to end up anywhere in output unescaped so attackers' scripts are never able to be injected.

Collapse
richardtallent_70 profile image
Richard Tallent

No one cares about semantics verbs. Using POST for API endpoints solves an entire class of link-based attacks. We should of course still use CSRF and other mitigations, but the semantic purism argument is a weak one, IMHO.

Collapse
guneyozsan profile image
Guney Ozsan

Not POST but using header authentication an all endpoints can add a layer of security. But this is extra. Nathan's point is well told.

Collapse
mandaputtra profile image
Manda Putra

I just follow along your articles with devs tool open haha

Collapse
michi profile image
Michael Z

While those vectors may not be working today, we never know what new bug tomorrow will bring, and therefore we should still do our best to prevent API's from being exploitable.

Wouldn't CORB prevent JSON hijacking in modern browers? developers.google.com/web/updates/...

Collapse
davis profile image
Davis

TLDR: use Auth Headers instead of cookies in your API and don't use script tags to call an API?? We shouldnt be looking at the hacks that giants use and instead use actual security improvements. CSP headers!

Collapse
antogarand profile image
Antony Garand Author

This was about 10 years ago, when CORS and CSP didn't exist

Collapse
arpitgogia profile image
Arpit Gogia

Super interesting post, thanks for this!

Collapse
nssimeonov profile image
Templar++

Amazing article. Thank you!

Collapse
ogonkov profile image
Alexey

If you have some js on your site, that can modify your constructor, you already hijacked, isn't it?

Collapse
antogarand profile image
Antony Garand Author

This attack is used to steal data from another website.

Say you're on dev.to, you don't want dev.to to access your emails!
But dev.to can still execute their own scripts, which makes sense.

Collapse
datvm profile image
Luke Vo • Edited

Pardon my noob but shouldn't it be fixed with CORS instead?

Thread Thread
antogarand profile image
Antony Garand Author

Cors wouldn't work on old browsers, and CORS is also used on the source site to limit what can be accessed from this website.

What is happening here is the opposite: An attacking website want to access information from another one.

Also note that this vulnerability is over 10 years old, well older than CORS :)

Collapse
lexlohr profile image
Alex Lohr

I did something similar, but I used location.href=... to redirect to the site from which the data was supposed to be used.

Collapse
dchenk profile image
Dmitriy

So just use Protocol Buffers in your API response.

Collapse
rotexhawk profile image
rotexhawk

Great article. Small typo. Agaim!

Collapse
antogarand profile image
Antony Garand Author

Thanks, just fixed it!

Collapse
nicolasguzca profile image
Nick

Awesome post Antony! I always wondered about the for loop.

Collapse
kataras profile image
Gerasimos (Makis) Maropoulos

Amazing, I knew some of those individually however this extremely helpful post is like a complete paper with references, so I can bookmark this, thank you Antony!

Collapse
designpuddle profile image
Chris Bertrand

Great post! Very insightful

Collapse
heshiebee profile image
Heshie Brody

Awesome stuff!!

Collapse
thomashighbaugh profile image
Thomas Leon Highbaugh

nice piece and good use of the notation to illuminate the point.

Look forward to seeing more from you!

Collapse
kureikain profile image
kureikain

Thank you for great article. I include it on my news letter: betterdev.link/issues/76

Collapse
antogarand profile image
Antony Garand Author

This is great!

I've been following this newsletter since like edition 20, it's good to see my content being part of it.

Collapse
abhijitparida profile image
Abhijit Parida

Is the API still vulnerable if CORS is disabled?

Collapse
antogarand profile image
Antony Garand Author

No, this has been fixed about 10 years ago in the ECMA specs, no modern browsers are vulnerable to this specific approach.

Collapse
to_mos profile image
Comment marked as low quality/non-constructive by the community. View Code of Conduct
𝓣𝓸-𝓢𝓸𝓼 • Edited

If you are going to put links on your article please drop the condescending lmddgtfy.com idiocy...that's just lackadaisical and boorish to readers. The point of an article's links are to support the content it talks about, not insult readers by demonstrating a lack of effort on your part. I would expect this behavior when someone asks a simple question on a chat forum or the YouTube comments area but a dev.to article, REALLY?

Collapse
antogarand profile image
Antony Garand Author

So, after writing up a full article, including a reference section and links through the post, having a link towards a search result page is a lack of effort on my part and an insult to the readers?

That's my writing style and if you don't like it, you're free to not read it or not click on the links, specially since there should be a link preview on the bottom left corner of your browser.

Finally, considering this article has over 65k views and you're the only negative comment, I would consider you to be the exception.

Hope you enjoyed the article, but please provide your comments in a more constructive manner next time I include a lmddgtfy.net link!

Collapse
to_mos profile image
𝓣𝓸-𝓢𝓸𝓼 • Edited

I'm sorry if you consider my comment "negative" that was not the intention, it was a trivial request. The lmddgtfy link just came off really condescending to me so I over reacted, apologies for that. I instantly close any links that go to let me search that for you sites as the lmgtfy.com website has a nice little "That wasn't so hard was it?" message right before it clicks search. After being insulted by this many times I had assumed that the duck duck go version did the same thing and closed the page before it even clicked search.

"please provide your comments in a more constructive manner next time I include a lmddgtfy.net link!"
Ok, instead of providing a lmddgtfy link with a lengthy 5 second animation suggesting that the reader lacks the brain power to search themselves. Just do a direct link to the search result like so duckduckgo.com/?q=JSON+hijacking, it's faster and more direct.

Although if someone is interested in the topic they will search for it themselves, it seems a little redundant to open a search result for an article. Try linking in other interesting reads related to the topic, maybe even some dev.to ones. Hope that's constructive enough for you. :)

I did love the article though!