On May 17, 2012, at 7:07 PM, Daniel Friesen wrote:
On Wed, 16 May 2012 19:46:26 -0700, Roan Kattouw roan.kattouw@gmail.com wrote:
On Wed, May 16, 2012 at 7:32 PM, Terry Chay tchay@wikimedia.org wrote:
I thought http://www.mediawiki.org/wiki/Manual:Edit_token protects against this as it is required for an edit: http://www.mediawiki.org/wiki/API:Edit
Not if you can read the data using the Object/Array constructor hacks you described. The potential for data leakage includes token leakage, and once you get the API to leak a token you can create a hidden form on the page that POSTs all the right data (including the token) to the action=edit API and call .submit() on the form.
Roan
Actually I don't think the object constructor or getter hacks work.
jQuery('<script />', {src: "https://en.wikipedia.org/w/api.php?action=query&prop=info&titles=Mai...'); api.php:1 Uncaught SyntaxError: Unexpected token :
We don't wrap the JSON in ()'s (it would be invalid JSON). And as a result the {} is in a statement scope instead of an expression scope. As a result the JavaScript engine tries to parse this as a block of code rather than an object. Naturally since "asdf": is not valid code the JavaScript engine quickly fatals considering this a SyntaxError before it can evaluate anything.
It only works for array because [] doesn't have the ambiguity that {} has.
-- ~Daniel Friesen (Dantman, Nadir-Seen-Fire) [http://daniel.friesen.name]
Indeed. Browsers that evaluate the JSON response as JavaScript (rather than JSON, plain text) would quickly fail with a SyntaxError.
For the long-term future, though, since format=json has an application/json header, browsers shouldn't evaluate it as javascript at all. Mozilla Firefox has already started to adhere to this practice. Hopefully other browsers will follow.
Because until then, although an entirely different matter not related to MediaWiki API, the following would be evaluated in those browsers:
Content-Type:application/json; charset=utf-8
{"foo": (function () { var s = document.createElement('script'); /* ... */ }())}
You get the idea..
-- Krinkle