{"id":240,"date":"2012-02-10T11:44:10","date_gmt":"2012-02-10T19:44:10","guid":{"rendered":"http:\/\/blog.mozilla.org\/webappsec\/?p=240"},"modified":"2015-12-21T15:21:18","modified_gmt":"2015-12-21T23:21:18","slug":"using-json-for-private-data","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/","title":{"rendered":"Using JSON for Private Data"},"content":{"rendered":"<div>\n<p>Sometimes we&#8217;re asked for guidance on something and the result seems worth sharing; this one is about useful things to consider when using JSON for information that needs to stay secret.<\/p>\n<p>If you&#8217;re using JSON for private data; make sure you&#8217;ve fixed the <a href=\"https:\/\/wiki.mozilla.org\/WebAppSec\/Secure_Coding_Guidelines#Preventing_CSRF\" rel=\"nofollow\">CSRF<\/a> side of things and everything will be OK. If you want to try to protect yourself in the (hopefully unlikely) event of your CSRF protection mechanisms failing, read on.<\/p>\n<p><!--more-->There are 4 ways commonly used ways to transfer JSON data:<br \/>\n1) JSONP<br \/>\n2) var assignment<br \/>\n3) JavaScript arrays<br \/>\n4) plain JSON (e.g. native browser JSON support, or Crockford&#8217;s json2.js)<\/p>\n<p>Of these, I can only really recommend using option 4. Let&#8217;s look at the known attacks against the others to understand why:<\/p>\n<p>JSONP and var assignment are similar and designed to achieve the same goal; allow an application to consume JSON data from a server in a different domain. In the first, the data is wrapped such that the response from the server is a valid script that will call a function in the embedding application with an object supplied by the server:<\/p>\n<p><code>callback({\"secret\":\"the treasure is buried under the tall tree\"});<\/code><\/p>\n<p>In the second, the data is wrapped such that the response is a valid script that will assign the object supplied by the server to a variable that can then be accessed by the embedding application.<\/p>\n<p><code>var result ={\"secret\":\"the treasure is buried under the tall tree\"};<\/code><\/p>\n<p>Despite being designed to allow an application to consume data from servers on multiple domains, these techniques have often been used for another reason; until the advent of native JSON support in browsers, JSONP <a href=\"http:\/\/ejohn.org\/blog\/native-json-support-is-required\/\" rel=\"nofollow\">was faster (and scaled better)<\/a> than the alternative means of consuming data.<\/p>\n<p>The standard <strong>JSONP<\/strong> and <strong>var assignment<\/strong> attacks are essentially the same; they rely on the fact that the attacker is able to either predict or control the name of the destination; whether that be a callback or variable.<\/p>\n<p>Some implement JSONP or var assignment in such a way that the destination is not predictable to the attacker (derived from session information, or similar); this alone does not guarantee the safety of the data as attacks exist against some browsers that still allow the attacker to extract any information contained (read on for a description of some such techniques).<\/p>\n<p>The use of <strong>JavaScript arrays<\/strong> has been the cause of several well documented attacks in the past, most notably <a href=\"http:\/\/jeremiahgrossman.blogspot.com\/2006\/01\/advanced-web-attack-techniques-using.html\" rel=\"nofollow\">Jeremiah Grossman&#8217;s gmail contact hack<\/a>. This made use of a combination of two factors: 1) that, in some older browsers, it was possible to clobber the Array constructor to steal data from arrays and 2) javascript arrays, unlike valid JSON (which should be contained within a JavaScript object), are directly executable as script by the browser.<\/p>\n<p>While the above attack is not possible on any current browsers,<a href=\"http:\/\/directwebremoting.org\/blog\/joe\/2007\/03\/06\/json_is_not_as_safe_as_people_think_it_is_part_2.html\" rel=\"nofollow\">various people have developed variants of the Array constructor attack<\/a> (including attacks on <strong>javascript objects<\/strong>), <a href=\"http:\/\/www.thespanner.co.uk\/2011\/05\/30\/json-hijacking\/\" rel=\"nofollow\">some of which are purported to work on newer browsers in some cases<\/a> (although I can&#8217;t reproduce these results), so the use of any JSON technique which results in responses that are directly executable as script is to be discouraged.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes we&#8217;re asked for guidance on something and the result seems worth sharing; this one is about useful things to consider when using JSON for information that needs to stay &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/\">Read more<\/a><\/p>\n","protected":false},"author":401,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[121],"tags":[],"coauthors":[45532],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using JSON for Private Data - Mozilla Security Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mark Goodwin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/\",\"url\":\"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/\",\"name\":\"Using JSON for Private Data - Mozilla Security Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/#website\"},\"datePublished\":\"2012-02-10T19:44:10+00:00\",\"dateModified\":\"2015-12-21T23:21:18+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/f8cd6cae5862d9db51300db343c769c9\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/security\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using JSON for Private Data\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/security\/\",\"name\":\"Mozilla Security Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/security\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/f8cd6cae5862d9db51300db343c769c9\",\"name\":\"Mark Goodwin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/image\/0987c099d8ff38099c0d4aece7c3f0a5\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/01f288b6d43bba75d08b107c50222350?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/01f288b6d43bba75d08b107c50222350?s=96&d=identicon&r=g\",\"caption\":\"Mark Goodwin\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using JSON for Private Data - Mozilla Security Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/","twitter_misc":{"Written by":"Mark Goodwin","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/","url":"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/","name":"Using JSON for Private Data - Mozilla Security Blog","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/security\/#website"},"datePublished":"2012-02-10T19:44:10+00:00","dateModified":"2015-12-21T23:21:18+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/f8cd6cae5862d9db51300db343c769c9"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/security\/2012\/02\/10\/using-json-for-private-data\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/security\/"},{"@type":"ListItem","position":2,"name":"Using JSON for Private Data"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/security\/#website","url":"https:\/\/blog.mozilla.org\/security\/","name":"Mozilla Security Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/security\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/f8cd6cae5862d9db51300db343c769c9","name":"Mark Goodwin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/image\/0987c099d8ff38099c0d4aece7c3f0a5","url":"https:\/\/secure.gravatar.com\/avatar\/01f288b6d43bba75d08b107c50222350?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/01f288b6d43bba75d08b107c50222350?s=96&d=identicon&r=g","caption":"Mark Goodwin"}}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts\/240"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/users\/401"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/comments?post=240"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts\/240\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/media?parent=240"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/categories?post=240"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/tags?post=240"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/coauthors?post=240"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}