Security; AJAX; JSON; Satisfaction

Well, for a while I've been trying to prove that either it is, or isn't, possible to XSS a JSON return which is wrapped in { }.

While it is well known that it is possible to exploit the return of a JavaScript array, I've been trying to establish if it is also possible with generic objects conforming to the JSON standard.

JAVASCRIPT:
  1. {
  2.     "glossary": {
  3.         "title": "example glossary",
  4.         "GlossDiv": {
  5.             "title": "S",
  6.             "GlossList": {
  7.                 "GlossEntry": {
  8.                     "ID": "SGML",
  9.                     "SortAs": "SGML",
  10.                     "GlossTerm": "Standard Generalized Markup Language",
  11.                     "Acronym": "SGML",
  12.                     "Abbrev": "ISO 8879:1986",
  13.                     "GlossDef": {
  14.                         "para": "A meta-markup language, used to create markup languages such as DocBook.",
  15.                         "GlossSeeAlso": ["GML", "XML"]
  16.                     },
  17.                     "GlossSee": "markup"
  18.                 }
  19.             }
  20.         }
  21.     }
  22. }

This is the example JSON provided by json.org. If you encapsulate this directly in <script> tags then browsers will throw an error.

I have tried to overwrite the object constructor in all the major browsers. None of Yahoo's A-grade browsers will call the constructor for these object returns, because of the object exception.

I have come to the conclusion that browsers parse { } because as a script block not an object, but will not parse an actual object without a label. Tim and I were talking about this and agreed that the parser allows [] without a label for the construction of anonymous arrays to make multi-dimensional arrays. Good thinking Batman Tim!

What does all this mean? In effect that means that using a JSON return in as per the example wrapped in { } means it can't be used for XSS. Using a simple array return is still as vulnerable as ever.

Technorati Tags:
, , ,

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • Digg
  • DZone
  • Ma.gnolia
  • MisterWong
  • Reddit
  • scuttle
  • Slashdot
  • SphereIt
  • StumbleUpon
  • YahooMyWeb
  • Wists
discussion by DISQUS
Add New Comment
Viewing 2 comments — Sort by:
    nejucomo 1 week ago with 1 point

    This is surprising to me. I don't understand either why it doesn't parse, nor your explanation for why it does not parse.

    Look at this Spider Monkey session:
    js> {"foo": "bar"}
    typein:156: SyntaxError: invalid label:
    typein:156: {"foo": "bar"}
    typein:156: ......^
    js> {quz: "quux"}
    quux
    js> ({quack: "like a duck"}).quack
    like a duck
    js> ({quack: "like a duck", jump: "like a kangaroo"}).quack
    like a duck
    js> ({quack: "like a duck", jump: "like a kangaroo"}).jump
    like a kangaroo
    js> ({"boo": "like a ghost"}).boo
    like a ghost
    js> ({"boo": "like a ghost", "flash": "like a firefly"}).flash
    like a firefly
    js> {"boo": "like a ghost"}
    typein:165: SyntaxError: invalid label:
    typein:165: {"boo": "like a ghost"}
    typein:165: ......^


    -So to me it appears that there is some grammatical construct which I'm unfamiliar with interfering with the general grammar of object literals. Also, notice these work:

    js> x={"boo": "foo"}
    [object Object]
    js> var y = {"boo": "foo"}
    js> y
    [object Object]


    I guess the next step is to read the javascript grammar to understand what's happening here.

    Valid JSON is an anonymous Javascript object. As such to be syntactically correct it requires assignment to a variable. This is why including raw JSON will create a syntax error.

    Arrays on the other hand got a bit of syntactic sugar added to make anonymous arrays valid to allow for multidimensional arrays. This means including an unassigned array object is valid Javascript (but not JSON).

    It should be noted though that 3rd party Javascript needs something like AdSafe or Caja to make it safe before you can consider using it on your page. 3rd party scripts can overload Object constructors or other functions to get access to private data.