Hacker News new | comments | show | ask | jobs | submit login

I had a hunch that this is to prevent people from including the resource in a script tag - but I always wondered how they'd access the data as a JSON expression on its own should technically be a no-op when interpreted as JS (or so I thought).

The overridden array constructor was the missing link.

Though couldn't you have it easier by making sure your top-level JSON structure is always an object?

As far as I know, while a standalone array expression []; is a valid JS statement, a standalone object expression {}; is not and would produce a syntax error.

Someone had the same question as you in a comment.

>Wouldn't returning an object containing the array, instead of the array directly, also solve the problem?

And someone else replied

>No, that wouldn't solve the problem since the same attacks mentioned in the post could still be performed. Overriding the accessor methods to retrieve the info.

Except I don't think a JSON object is valid Javascript by itself.

What about a JSON object do you think is invalid Javascript?

It's a valid subset of Javascript (or at least was initially meant to be), but a JSON object (as opposed to an array) isn't a valid stand-alone Javascript expression, and an attempt to eval it will return an error:

    > eval('{"key": "value"}');
    SyntaxError: missing ; before statement
You can get around this by using parens:

    > eval('({"key": "value"})');
    Object { key: "value" }
But accidentally including a JSON URL in a script tag should fail to evaluate if there's an object at the top level.

All JSON literals are valid JS expressions but not all are valid statements. The two are different parts of the JS grammar.

As script blocks expect one or more statements to execute, the hack relies on the fact that some JSON (array literals) also happen to be valid statements in addition to expressions.

While the person you're responding to might genuinely be confused about JSON usually being valid JavaScript, arbitrary JSON isn't guaranteed to be: http://timelessrepo.com/json-isnt-a-javascript-subset

> Though couldn't you have it easier by making sure your top-level JSON structure is always an object?

Yes, this works too. You’re correct about any keys causing a syntax error.

.NET does this by wrapping things with {'d': data}, I always thought this was the reason.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact