New page wikitext, after the edit (new_wikitext ) | ''''JSONP''', i.e. [http://www.json.org/ JSON] with padding, proposed by Bob Ippolito,<ref>{{Cite web|url=http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/|title=Remote JSON - JSONP|last=Ippolito|first=Bob|date=|website=bob.ippoli.to|language=en|archive-url=|archive-date=|dead-url=|access-date=2017-02-10}}</ref> is used to request data from a server residing in a different domain than the client. This enables sharing of data bypassing [[same-origin policy]]. The policy disallows running [[JavaScript]] to read media [[Document Object Model|DOM]] elements or [[XMLHttpRequest|XHR]] data fetched from outside the page's origin. The aggregation of the site's scheme, port number and host name identifies as its origin. Due to inherent insecurities JSONP is being replaced by [[Cross-Origin Resource Sharing|CORS]].
== How JSONP works ==
The HTML <code><script></code> element is allowed to execute content retrieved from foreign origins. Services replying with pure JSON data were not able to share the data across domain before the adoption of CORS. For example, a request to a foreign service <code><nowiki>http://server.example.com/Users/1234</nowiki></code> may return a record for a person Foo in the JSON format, which, by definition, conforms to Javascript's object initializer syntax.
<source lang="html4strict" line="1">
{
"Name": "Foo",
"Id": 192.168.73.96,
"Rank": 7
}
</source>
Attempts to use the data across domain will result in a Javascript error.
<source lang="html4strict" line="1">
<script type="application/javascript"
src="http://server.example.com/Users/1234">
</script>
</source>
The browser will download the <code><script></code> file, evaluate its contents, mis-interpret the raw JSON data as a [[JavaScript syntax#Compound statements|block]], and throw a syntax error. Even if the data was interpreted as a JavaScript object literal, it could not be accessed by JavaScript running in the browser, since without a variable assignment, object literals are inaccessible.
In the JSONP usage pattern, the URL request pointed to by the <code>src</code> attribute in the <code><script></code> element returns JSON data, with JavaScript code (usually a function call) wrapped around it. This "wrapped payload" is then interpreted by the browser. In this way, a function that is already defined in the JavaScript environment can manipulate the JSON data. A typical JSONP request and response are shown below.
The function call to parseResponse() is the "P" of JSONP—the "padding" around the pure JSON, or according to some<ref>{{cite web|url=http://epimorph-pubx1.appspot.com/help.html |title=Experimental RDF result set to JSON translator |accessdate=February 20, 2012 |deadurl=yes |archiveurl=https://web.archive.org/web/20141115070803/http://epimorph-pubx1.appspot.com/help.html |archivedate=November 15, 2014 }}</ref> the "prefix".
Note that for JSONP to work, a server must reply with a response that includes the JSONP function. JSONP does not work with JSON-formatted results. The JSONP function invocation that gets sent back, and the payload that the function receives, must be agreed-upon by the client and server.
By convention, the server providing the JSON data offers the requesting website to name the JSONP function, typically using the name jsonp or [[callback (computer programming)|callback]] as the named query parameter field name, in its request to the server, e.g.,
<source lang="html4strict">
<script type="application/javascript"
src="http://server.example.com/Users/1234?callback=parseResponse">
</script>
</source>
In this example, the received payload would be:
<source lang="javascript">
parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});
</source>
== Script element injection ==
JSONP makes sense only when used with a script element. For each new JSONP request, the browser must add a new <code><script></code> element, or reuse an existing one. The former option—adding a new script element—is done via dynamic DOM manipulation, and is known as ''script element injection''. The <code><script></code> element is injected into the HTML DOM, with the URL of the desired JSONP endpoint set as the "src" attribute. This dynamic ''script element injection'' is usually done by a JavaScript helper library. [[jQuery]] and other frameworks have JSONP helper functions; there are also standalone options.<ref>{{cite web |url=http://pastebin.com/ADxHdCnB|title=example jsonp library on pastebin}}</ref><ref>{{cite web |url=https://github.com/robertodecurnex/J50Npi/|title=Basic JSONP helper (pure JS)}}</ref><ref>{{cite web |url=http://api.jquery.com/jQuery.getJSON/|title=jQuery's $.getJSON utility}}</ref>
An example of using jQuery to ''dynamically inject'' script element for a JSONP call looks like this:
<source lang="html4strict" line="1">
$.getScript("http://server.example.com/Users/192.168.73.96?callback=parseResponse");
</source>
After the element is injected, the browser evaluates the element, and performs an HTTP GET on the src URL, retrieving the content. Then the browser evaluates the return payload as JavaScript. This is typically a function invocation.
In that way, the use of JSONP can be said to ''allow browser pages to work around the [[same-origin policy]] via script element injection.''
The script runs within the scope of the including page and, as such, is still subject to cross-domain restrictions relative to the domain of the including page. This means that a web page cannot, for example, load a library hosted on another site via JSONP and then make XMLHttpRequest requests to that site (unless [[cross-origin resource sharing]] (CORS) is supported), although one could use such a library to make XMLHttpRequests to one's own site.
== Cross-domain requests using helper same-domain service ==
The JavaScript same-origin policy normally prevents browsers from reading responses to [[AJAX]] requests sent to a different domain (newer browsers that support [[Cross-Origin Resource Sharing|CORS]] allow relaxing this constraint with the foreign service's consent). A cooperating same-domain service can relay browser requests to a foreign server and respond with the foreign server's responses. This presents an alternative way of sharing data across domains where browsers do not regard CORS. (Malicious servers can steal web UI origins and lure unsuspecting users to visit the fake web UI origins).
== Security concerns ==
=== Untrusted third-party code ===
Including script tags from remote servers allows the remote servers to inject ''any'' content into a website. If the remote servers have vulnerabilities that allow JavaScript injection, the page served from the original server is exposed to an increased risk. If an attacker can inject any JavaScript into the original web page, then that code can retrieve additional JavaScript from any domain, bypassing [[same-origin policy]].<ref>{{cite web | url=https://www.blackhat.com/docs/eu-14/materials/eu-14-Hayak-Same-Origin-Method-Execution-Some-Exploiting-A-Callback-For-Same-Origin-Policy-Bypass.pdf | title=Same Origin Method Execution | date=2014-10-17 | accessdate=2014-10-22 | author=Ben Hayak}}</ref> The Content Security Policy HTTP Header lets web sites tell web browsers which domain scripts may be included from.
An effort was undertaken around 2011 to define a safer strict subset definition for JSONP<!--Is JSON-P important here? Seems to be synonyms--><ref name="JSON-P">{{cite web |url=http://www.json-p.org/ |title=Safer cross-domain Ajax with JSON-P/JSONP |work=JSON-P.org |accessdate=2011-10-30 |deadurl=yes |archiveurl=https://web.archive.org/web/20160304044218/http://www.json-p.org/ |archivedate=March 4, 2016}}</ref> that browsers would be able to enforce on script requests with a specific [[MIME]] type such as "application/json-p". If the response did not parse as strict JSONP, the browser could throw an error or just ignore the entire response. However, this approach was abandoned in favour of [[Cross-origin resource sharing|CORS]], and the correct MIME type for JSONP remains <code>application/javascript</code>.<ref>{{cite web |url=https://stackoverflow.com/a/3128948/569447 |first=Eli |last=Grey |title=Is this safe for providing JSONP? |work=stackoverflow.com |date=2010-06-27 |accessdate=2012-09-07 }}</ref>
=== Callback name manipulation and reflected file download attack ===
Unsanitized callback names may be used to pass malicious data to clients, bypassing the restrictions associated with <code>application/json</code> content type, as demonstrated in reflected file download (RFD) attack from 2014.<ref>{{cite web | url=https://www.trustwave.com/Resources/SpiderLabs-Blog/Reflected-File-Download---A-New-Web-Attack-Vector/ | title=Reflected File Download - A New Web Attack Vector | publisher=TrustWave | date=2014 | accessdate=2015-03-25 | author=Oren Hafif}}</ref>
Insecure JSONP endpoints can be also injected with malicious data.<ref>{{cite web|url=https://securitycafe.ro/2017/01/18/practical-jsonp-injection/ |title=Practical JSONP injection}}</ref>
==== Cross-site request forgery ====
Naive deployments of JSONP are subject to [[cross-site request forgery]] (CSRF or XSRF) attacks.<ref>{{cite web |url=http://jeremiahgrossman.blogspot.com/2006/01/advanced-web-attack-techniques-using.html |title=Advanced Web Attack Techniques using GMail |first=Jeremiah |last=Grossman |date=January 27, 2006 |accessdate=July 3, 2009}}</ref> Because the HTML <code><script></code> tag does not respect the [[same-origin policy]] in web browser implementations, a malicious page can request and obtain JSON data belonging to another site. This will allow the JSON-encoded data to be evaluated in the context of the malicious page, possibly divulging passwords or other sensitive data if the user is currently logged into the other site.
This is problematic only if the JSON-encoded data contains sensitive information which should not be disclosed to a third party, and the server depends on the [[same-origin policy]] of the browser to block the delivery of the data in the case of an unauthorized request. This security dependency on the browser's same-origin policy can be avoided by the server determining if the request is authorized and only putting the data on the wire if it is. Exclusive use of [[HTTP cookie|cookies]] for determining if a request is authorized should be avoided as it is subject to [[cross-site request forgery]].
=== Rosetta Flash ===
Rosetta Flash is an exploitation technique that allows an attacker to exploit servers with a vulnerable JSONP endpoint by causing [[Adobe Flash Player]] to believe that an attacker-specified Flash applet originated on the vulnerable server. Flash Player implements [[same-origin policy]] allowing to make requests (with cookies) and receive responses from the hosting site. The applet can then send the retrieved data back to the attacker. This is a cross-origin exploit with an impact similar to embedding an arbitrary Flash applet in the vulnerable domain. The exploit uses an ActionScript payload compiled to an SWF file composed entirely of alphanumeric characters by crafting a [[zlib]] stream with a particular header and [[DEFLATE]] blocks with ad-hoc [[Huffman coding]]. The resulting alphanumeric-only SWF file is then used as the callback parameter of a JSONP call. High-profile sites such as Google, YouTube, Twitter, Yahoo!, Yandex, LinkedIn, eBay, Instagram and Tumblr were all vulnerable until July 2014.<ref>{{cite web|last1=Michele|first1=Spagnuolo|title=Abusing JSONP with Rosetta Flash|url=http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/|accessdate=July 20, 2014}}</ref> This vulnerability was discovered and published by Google security engineer Michele Spagnuolo<ref>{{cite web |url=https://www.google.com/about/appsecurity/research/ |title=Google - list of software vulnerabilities discovered or fixed by Googlers|accessdate=July 29, 2014}}</ref> and has [[Common Vulnerabilities and Exposures|CVE]] 2014-4671<ref>{{cite web |url=http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4671 |title=MITRE: CVE-2014-4671 |accessdate=July 29, 2014}}</ref> and CVE 2014-5333.<ref>{{cite web |url=http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-5333 |title=MITRE: CVE-2014-5333 |accessdate=August 21, 2014}}</ref> Adobe Flash Player release version 14.0.0.145, released on July 8, 2014, introduced stronger validation of Flash files,<ref>{{cite web |url=http://helpx.adobe.com/security/products/flash-player/apsb14-17.html |title=Adobe Security Bulletin APSB14-17 |accessdate=July 29, 2014}}</ref> and in version 14.0.0.176, released on August 12, 2014, finalized the fix,<ref>{{cite web |url=http://helpx.adobe.com/security/products/flash-player/apsb14-18.html |title=Adobe Security Bulletin APSB14-18 |accessdate=August 21, 2014}}</ref> preventing this exploit from working.
== History ==
In July 2005, George Jempty suggested an optional variable assignment be prepended to JSON.<ref>{{cite web|url=http://htmatters.net/htm/1/2005/07/evaling-JSON.cfm |title=eval'ing JSON |date=July 19, 2005 |deadurl=yes |archiveurl=https://web.archive.org/web/20060212113746/http://htmatters.net/htm/1/2005/07/evaling-JSON.cfm |archivedate=February 12, 2006 }}</ref><ref>{{cite web |url=http://tech.groups.yahoo.com/group/json/message/82 |title=json: Message: Re: Comments |date=August 17, 2005}}</ref> The original proposal for JSONP, where the padding is a callback function, appears to have been made by Bob Ippolito in December 2005<ref>{{cite web |url=http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/ |work=from __future__ import * |title=Remote JSON - JSONP |publisher=Bob.pythonmac.org |date=December 5, 2005 |accessdate=September 8, 2008}}</ref> and is now used by many [[Web 2.0]] applications such as [[Dojo Toolkit]], [[Google Web Toolkit]] and [[Web service]]s.
== See also ==
* Cross-origin resource sharing (CORS)
* [[Web Messaging|Cross-document messaging]]
== References ==
{{Reflist}}
== External links ==
* [http://www.vcarrer.com/2010/11/about-jsonp-in-javascript.html ''About JSONP in JavaScript'']
* [https://code.google.com/p/jsonp-java/ server side filter wraps any response into a jsonp callback]{{snd}}done with jsonp-java source code
* [http://quaxio.com/jsonp_handcrafted_flash_files/ Potential security issues related to JSONP]
* [https://datatables.net/examples/server_side/jsonp.html JSONP data source for remote domains]
[[Category:Ajax (programming)]]
[[Category:JSON]]' |
Unified diff of changes made by edit (edit_diff ) | '@@ -1,4 +1,98 @@
-*
+'''JSONP''', i.e. [http://www.json.org/ JSON] with padding, proposed by Bob Ippolito,<ref>{{Cite web|url=http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/|title=Remote JSON - JSONP|last=Ippolito|first=Bob|date=|website=bob.ippoli.to|language=en|archive-url=|archive-date=|dead-url=|access-date=2017-02-10}}</ref> is used to request data from a server residing in a different domain than the client. This enables sharing of data bypassing [[same-origin policy]]. The policy disallows running [[JavaScript]] to read media [[Document Object Model|DOM]] elements or [[XMLHttpRequest|XHR]] data fetched from outside the page's origin. The aggregation of the site's scheme, port number and host name identifies as its origin. Due to inherent insecurities JSONP is being replaced by [[Cross-Origin Resource Sharing|CORS]].
+
+== How JSONP works ==
+The HTML <code><script></code> element is allowed to execute content retrieved from foreign origins. Services replying with pure JSON data were not able to share the data across domain before the adoption of CORS. For example, a request to a foreign service <code><nowiki>http://server.example.com/Users/1234</nowiki></code> may return a record for a person Foo in the JSON format, which, by definition, conforms to Javascript's object initializer syntax.
+<source lang="html4strict" line="1">
+{
+ "Name": "Foo",
+ "Id": 192.168.73.96,
+ "Rank": 7
+}
+</source>
+
+Attempts to use the data across domain will result in a Javascript error.
+
+<source lang="html4strict" line="1">
+<script type="application/javascript"
+ src="http://server.example.com/Users/1234">
+</script>
+</source>
+
+The browser will download the <code><script></code> file, evaluate its contents, mis-interpret the raw JSON data as a [[JavaScript syntax#Compound statements|block]], and throw a syntax error. Even if the data was interpreted as a JavaScript object literal, it could not be accessed by JavaScript running in the browser, since without a variable assignment, object literals are inaccessible.
+
+In the JSONP usage pattern, the URL request pointed to by the <code>src</code> attribute in the <code><script></code> element returns JSON data, with JavaScript code (usually a function call) wrapped around it. This "wrapped payload" is then interpreted by the browser. In this way, a function that is already defined in the JavaScript environment can manipulate the JSON data. A typical JSONP request and response are shown below.
+
+The function call to parseResponse() is the "P" of JSONP—the "padding" around the pure JSON, or according to some<ref>{{cite web|url=http://epimorph-pubx1.appspot.com/help.html |title=Experimental RDF result set to JSON translator |accessdate=February 20, 2012 |deadurl=yes |archiveurl=https://web.archive.org/web/20141115070803/http://epimorph-pubx1.appspot.com/help.html |archivedate=November 15, 2014 }}</ref> the "prefix".
+
+Note that for JSONP to work, a server must reply with a response that includes the JSONP function. JSONP does not work with JSON-formatted results. The JSONP function invocation that gets sent back, and the payload that the function receives, must be agreed-upon by the client and server.
+
+By convention, the server providing the JSON data offers the requesting website to name the JSONP function, typically using the name jsonp or [[callback (computer programming)|callback]] as the named query parameter field name, in its request to the server, e.g.,
+
+<source lang="html4strict">
+<script type="application/javascript"
+ src="http://server.example.com/Users/1234?callback=parseResponse">
+</script>
+</source>
+
+In this example, the received payload would be:
+
+<source lang="javascript">
+parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});
+</source>
+
+== Script element injection ==
+JSONP makes sense only when used with a script element. For each new JSONP request, the browser must add a new <code><script></code> element, or reuse an existing one. The former option—adding a new script element—is done via dynamic DOM manipulation, and is known as ''script element injection''. The <code><script></code> element is injected into the HTML DOM, with the URL of the desired JSONP endpoint set as the "src" attribute. This dynamic ''script element injection'' is usually done by a JavaScript helper library. [[jQuery]] and other frameworks have JSONP helper functions; there are also standalone options.<ref>{{cite web |url=http://pastebin.com/ADxHdCnB|title=example jsonp library on pastebin}}</ref><ref>{{cite web |url=https://github.com/robertodecurnex/J50Npi/|title=Basic JSONP helper (pure JS)}}</ref><ref>{{cite web |url=http://api.jquery.com/jQuery.getJSON/|title=jQuery's $.getJSON utility}}</ref>
+
+An example of using jQuery to ''dynamically inject'' script element for a JSONP call looks like this:
+
+<source lang="html4strict" line="1">
+$.getScript("http://server.example.com/Users/192.168.73.96?callback=parseResponse");
+</source>
+
+After the element is injected, the browser evaluates the element, and performs an HTTP GET on the src URL, retrieving the content. Then the browser evaluates the return payload as JavaScript. This is typically a function invocation.
+
+In that way, the use of JSONP can be said to ''allow browser pages to work around the [[same-origin policy]] via script element injection.''
+
+The script runs within the scope of the including page and, as such, is still subject to cross-domain restrictions relative to the domain of the including page. This means that a web page cannot, for example, load a library hosted on another site via JSONP and then make XMLHttpRequest requests to that site (unless [[cross-origin resource sharing]] (CORS) is supported), although one could use such a library to make XMLHttpRequests to one's own site.
+
+== Cross-domain requests using helper same-domain service ==
+The JavaScript same-origin policy normally prevents browsers from reading responses to [[AJAX]] requests sent to a different domain (newer browsers that support [[Cross-Origin Resource Sharing|CORS]] allow relaxing this constraint with the foreign service's consent). A cooperating same-domain service can relay browser requests to a foreign server and respond with the foreign server's responses. This presents an alternative way of sharing data across domains where browsers do not regard CORS. (Malicious servers can steal web UI origins and lure unsuspecting users to visit the fake web UI origins).
+
+== Security concerns ==
+
+=== Untrusted third-party code ===
+Including script tags from remote servers allows the remote servers to inject ''any'' content into a website. If the remote servers have vulnerabilities that allow JavaScript injection, the page served from the original server is exposed to an increased risk. If an attacker can inject any JavaScript into the original web page, then that code can retrieve additional JavaScript from any domain, bypassing [[same-origin policy]].<ref>{{cite web | url=https://www.blackhat.com/docs/eu-14/materials/eu-14-Hayak-Same-Origin-Method-Execution-Some-Exploiting-A-Callback-For-Same-Origin-Policy-Bypass.pdf | title=Same Origin Method Execution | date=2014-10-17 | accessdate=2014-10-22 | author=Ben Hayak}}</ref> The Content Security Policy HTTP Header lets web sites tell web browsers which domain scripts may be included from.
+
+An effort was undertaken around 2011 to define a safer strict subset definition for JSONP<!--Is JSON-P important here? Seems to be synonyms--><ref name="JSON-P">{{cite web |url=http://www.json-p.org/ |title=Safer cross-domain Ajax with JSON-P/JSONP |work=JSON-P.org |accessdate=2011-10-30 |deadurl=yes |archiveurl=https://web.archive.org/web/20160304044218/http://www.json-p.org/ |archivedate=March 4, 2016}}</ref> that browsers would be able to enforce on script requests with a specific [[MIME]] type such as "application/json-p". If the response did not parse as strict JSONP, the browser could throw an error or just ignore the entire response. However, this approach was abandoned in favour of [[Cross-origin resource sharing|CORS]], and the correct MIME type for JSONP remains <code>application/javascript</code>.<ref>{{cite web |url=https://stackoverflow.com/a/3128948/569447 |first=Eli |last=Grey |title=Is this safe for providing JSONP? |work=stackoverflow.com |date=2010-06-27 |accessdate=2012-09-07 }}</ref>
+
+=== Callback name manipulation and reflected file download attack ===
+Unsanitized callback names may be used to pass malicious data to clients, bypassing the restrictions associated with <code>application/json</code> content type, as demonstrated in reflected file download (RFD) attack from 2014.<ref>{{cite web | url=https://www.trustwave.com/Resources/SpiderLabs-Blog/Reflected-File-Download---A-New-Web-Attack-Vector/ | title=Reflected File Download - A New Web Attack Vector | publisher=TrustWave | date=2014 | accessdate=2015-03-25 | author=Oren Hafif}}</ref>
+
+Insecure JSONP endpoints can be also injected with malicious data.<ref>{{cite web|url=https://securitycafe.ro/2017/01/18/practical-jsonp-injection/ |title=Practical JSONP injection}}</ref>
+
+==== Cross-site request forgery ====
+Naive deployments of JSONP are subject to [[cross-site request forgery]] (CSRF or XSRF) attacks.<ref>{{cite web |url=http://jeremiahgrossman.blogspot.com/2006/01/advanced-web-attack-techniques-using.html |title=Advanced Web Attack Techniques using GMail |first=Jeremiah |last=Grossman |date=January 27, 2006 |accessdate=July 3, 2009}}</ref> Because the HTML <code><script></code> tag does not respect the [[same-origin policy]] in web browser implementations, a malicious page can request and obtain JSON data belonging to another site. This will allow the JSON-encoded data to be evaluated in the context of the malicious page, possibly divulging passwords or other sensitive data if the user is currently logged into the other site.
+
+This is problematic only if the JSON-encoded data contains sensitive information which should not be disclosed to a third party, and the server depends on the [[same-origin policy]] of the browser to block the delivery of the data in the case of an unauthorized request. This security dependency on the browser's same-origin policy can be avoided by the server determining if the request is authorized and only putting the data on the wire if it is. Exclusive use of [[HTTP cookie|cookies]] for determining if a request is authorized should be avoided as it is subject to [[cross-site request forgery]].
+
+=== Rosetta Flash ===
+Rosetta Flash is an exploitation technique that allows an attacker to exploit servers with a vulnerable JSONP endpoint by causing [[Adobe Flash Player]] to believe that an attacker-specified Flash applet originated on the vulnerable server. Flash Player implements [[same-origin policy]] allowing to make requests (with cookies) and receive responses from the hosting site. The applet can then send the retrieved data back to the attacker. This is a cross-origin exploit with an impact similar to embedding an arbitrary Flash applet in the vulnerable domain. The exploit uses an ActionScript payload compiled to an SWF file composed entirely of alphanumeric characters by crafting a [[zlib]] stream with a particular header and [[DEFLATE]] blocks with ad-hoc [[Huffman coding]]. The resulting alphanumeric-only SWF file is then used as the callback parameter of a JSONP call. High-profile sites such as Google, YouTube, Twitter, Yahoo!, Yandex, LinkedIn, eBay, Instagram and Tumblr were all vulnerable until July 2014.<ref>{{cite web|last1=Michele|first1=Spagnuolo|title=Abusing JSONP with Rosetta Flash|url=http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/|accessdate=July 20, 2014}}</ref> This vulnerability was discovered and published by Google security engineer Michele Spagnuolo<ref>{{cite web |url=https://www.google.com/about/appsecurity/research/ |title=Google - list of software vulnerabilities discovered or fixed by Googlers|accessdate=July 29, 2014}}</ref> and has [[Common Vulnerabilities and Exposures|CVE]] 2014-4671<ref>{{cite web |url=http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4671 |title=MITRE: CVE-2014-4671 |accessdate=July 29, 2014}}</ref> and CVE 2014-5333.<ref>{{cite web |url=http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-5333 |title=MITRE: CVE-2014-5333 |accessdate=August 21, 2014}}</ref> Adobe Flash Player release version 14.0.0.145, released on July 8, 2014, introduced stronger validation of Flash files,<ref>{{cite web |url=http://helpx.adobe.com/security/products/flash-player/apsb14-17.html |title=Adobe Security Bulletin APSB14-17 |accessdate=July 29, 2014}}</ref> and in version 14.0.0.176, released on August 12, 2014, finalized the fix,<ref>{{cite web |url=http://helpx.adobe.com/security/products/flash-player/apsb14-18.html |title=Adobe Security Bulletin APSB14-18 |accessdate=August 21, 2014}}</ref> preventing this exploit from working.
+
+== History ==
+In July 2005, George Jempty suggested an optional variable assignment be prepended to JSON.<ref>{{cite web|url=http://htmatters.net/htm/1/2005/07/evaling-JSON.cfm |title=eval'ing JSON |date=July 19, 2005 |deadurl=yes |archiveurl=https://web.archive.org/web/20060212113746/http://htmatters.net/htm/1/2005/07/evaling-JSON.cfm |archivedate=February 12, 2006 }}</ref><ref>{{cite web |url=http://tech.groups.yahoo.com/group/json/message/82 |title=json: Message: Re: Comments |date=August 17, 2005}}</ref> The original proposal for JSONP, where the padding is a callback function, appears to have been made by Bob Ippolito in December 2005<ref>{{cite web |url=http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/ |work=from __future__ import * |title=Remote JSON - JSONP |publisher=Bob.pythonmac.org |date=December 5, 2005 |accessdate=September 8, 2008}}</ref> and is now used by many [[Web 2.0]] applications such as [[Dojo Toolkit]], [[Google Web Toolkit]] and [[Web service]]s.
+
+== See also ==
+* Cross-origin resource sharing (CORS)
+* [[Web Messaging|Cross-document messaging]]
+
+== References ==
+{{Reflist}}
+
+== External links ==
+* [http://www.vcarrer.com/2010/11/about-jsonp-in-javascript.html ''About JSONP in JavaScript'']
+* [https://code.google.com/p/jsonp-java/ server side filter wraps any response into a jsonp callback]{{snd}}done with jsonp-java source code
+* [http://quaxio.com/jsonp_handcrafted_flash_files/ Potential security issues related to JSONP]
+* [https://datatables.net/examples/server_side/jsonp.html JSONP data source for remote domains]
[[Category:Ajax (programming)]]
[[Category:JSON]]
' |
Lines added in edit (added_lines ) | [
0 => ''''JSONP''', i.e. [http://www.json.org/ JSON] with padding, proposed by Bob Ippolito,<ref>{{Cite web|url=http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/|title=Remote JSON - JSONP|last=Ippolito|first=Bob|date=|website=bob.ippoli.to|language=en|archive-url=|archive-date=|dead-url=|access-date=2017-02-10}}</ref> is used to request data from a server residing in a different domain than the client. This enables sharing of data bypassing [[same-origin policy]]. The policy disallows running [[JavaScript]] to read media [[Document Object Model|DOM]] elements or [[XMLHttpRequest|XHR]] data fetched from outside the page's origin. The aggregation of the site's scheme, port number and host name identifies as its origin. Due to inherent insecurities JSONP is being replaced by [[Cross-Origin Resource Sharing|CORS]].',
1 => false,
2 => '== How JSONP works ==',
3 => 'The HTML <code><script></code> element is allowed to execute content retrieved from foreign origins. Services replying with pure JSON data were not able to share the data across domain before the adoption of CORS. For example, a request to a foreign service <code><nowiki>http://server.example.com/Users/1234</nowiki></code> may return a record for a person Foo in the JSON format, which, by definition, conforms to Javascript's object initializer syntax. ',
4 => '<source lang="html4strict" line="1">',
5 => '{',
6 => ' "Name": "Foo",',
7 => ' "Id": 192.168.73.96,',
8 => ' "Rank": 7',
9 => '}',
10 => '</source>',
11 => false,
12 => 'Attempts to use the data across domain will result in a Javascript error.',
13 => false,
14 => '<source lang="html4strict" line="1">',
15 => '<script type="application/javascript"',
16 => ' src="http://server.example.com/Users/1234">',
17 => '</script>',
18 => '</source>',
19 => false,
20 => 'The browser will download the <code><script></code> file, evaluate its contents, mis-interpret the raw JSON data as a [[JavaScript syntax#Compound statements|block]], and throw a syntax error. Even if the data was interpreted as a JavaScript object literal, it could not be accessed by JavaScript running in the browser, since without a variable assignment, object literals are inaccessible.',
21 => false,
22 => 'In the JSONP usage pattern, the URL request pointed to by the <code>src</code> attribute in the <code><script></code> element returns JSON data, with JavaScript code (usually a function call) wrapped around it. This "wrapped payload" is then interpreted by the browser. In this way, a function that is already defined in the JavaScript environment can manipulate the JSON data. A typical JSONP request and response are shown below.',
23 => false,
24 => 'The function call to parseResponse() is the "P" of JSONP—the "padding" around the pure JSON, or according to some<ref>{{cite web|url=http://epimorph-pubx1.appspot.com/help.html |title=Experimental RDF result set to JSON translator |accessdate=February 20, 2012 |deadurl=yes |archiveurl=https://web.archive.org/web/20141115070803/http://epimorph-pubx1.appspot.com/help.html |archivedate=November 15, 2014 }}</ref> the "prefix".',
25 => false,
26 => 'Note that for JSONP to work, a server must reply with a response that includes the JSONP function. JSONP does not work with JSON-formatted results. The JSONP function invocation that gets sent back, and the payload that the function receives, must be agreed-upon by the client and server.',
27 => false,
28 => 'By convention, the server providing the JSON data offers the requesting website to name the JSONP function, typically using the name jsonp or [[callback (computer programming)|callback]] as the named query parameter field name, in its request to the server, e.g.,',
29 => false,
30 => '<source lang="html4strict">',
31 => '<script type="application/javascript"',
32 => ' src="http://server.example.com/Users/1234?callback=parseResponse">',
33 => '</script>',
34 => '</source>',
35 => false,
36 => 'In this example, the received payload would be:',
37 => false,
38 => '<source lang="javascript">',
39 => 'parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});',
40 => '</source>',
41 => false,
42 => '== Script element injection ==',
43 => 'JSONP makes sense only when used with a script element. For each new JSONP request, the browser must add a new <code><script></code> element, or reuse an existing one. The former option—adding a new script element—is done via dynamic DOM manipulation, and is known as ''script element injection''. The <code><script></code> element is injected into the HTML DOM, with the URL of the desired JSONP endpoint set as the "src" attribute. This dynamic ''script element injection'' is usually done by a JavaScript helper library. [[jQuery]] and other frameworks have JSONP helper functions; there are also standalone options.<ref>{{cite web |url=http://pastebin.com/ADxHdCnB|title=example jsonp library on pastebin}}</ref><ref>{{cite web |url=https://github.com/robertodecurnex/J50Npi/|title=Basic JSONP helper (pure JS)}}</ref><ref>{{cite web |url=http://api.jquery.com/jQuery.getJSON/|title=jQuery's $.getJSON utility}}</ref>',
44 => false,
45 => 'An example of using jQuery to ''dynamically inject'' script element for a JSONP call looks like this:',
46 => false,
47 => '<source lang="html4strict" line="1">',
48 => '$.getScript("http://server.example.com/Users/192.168.73.96?callback=parseResponse");',
49 => '</source>',
50 => false,
51 => 'After the element is injected, the browser evaluates the element, and performs an HTTP GET on the src URL, retrieving the content. Then the browser evaluates the return payload as JavaScript. This is typically a function invocation.',
52 => false,
53 => 'In that way, the use of JSONP can be said to ''allow browser pages to work around the [[same-origin policy]] via script element injection.''',
54 => false,
55 => 'The script runs within the scope of the including page and, as such, is still subject to cross-domain restrictions relative to the domain of the including page. This means that a web page cannot, for example, load a library hosted on another site via JSONP and then make XMLHttpRequest requests to that site (unless [[cross-origin resource sharing]] (CORS) is supported), although one could use such a library to make XMLHttpRequests to one's own site.',
56 => false,
57 => '== Cross-domain requests using helper same-domain service ==',
58 => 'The JavaScript same-origin policy normally prevents browsers from reading responses to [[AJAX]] requests sent to a different domain (newer browsers that support [[Cross-Origin Resource Sharing|CORS]] allow relaxing this constraint with the foreign service's consent). A cooperating same-domain service can relay browser requests to a foreign server and respond with the foreign server's responses. This presents an alternative way of sharing data across domains where browsers do not regard CORS. (Malicious servers can steal web UI origins and lure unsuspecting users to visit the fake web UI origins).',
59 => false,
60 => '== Security concerns ==',
61 => false,
62 => '=== Untrusted third-party code ===',
63 => 'Including script tags from remote servers allows the remote servers to inject ''any'' content into a website. If the remote servers have vulnerabilities that allow JavaScript injection, the page served from the original server is exposed to an increased risk. If an attacker can inject any JavaScript into the original web page, then that code can retrieve additional JavaScript from any domain, bypassing [[same-origin policy]].<ref>{{cite web | url=https://www.blackhat.com/docs/eu-14/materials/eu-14-Hayak-Same-Origin-Method-Execution-Some-Exploiting-A-Callback-For-Same-Origin-Policy-Bypass.pdf | title=Same Origin Method Execution | date=2014-10-17 | accessdate=2014-10-22 | author=Ben Hayak}}</ref> The Content Security Policy HTTP Header lets web sites tell web browsers which domain scripts may be included from.',
64 => false,
65 => 'An effort was undertaken around 2011 to define a safer strict subset definition for JSONP<!--Is JSON-P important here? Seems to be synonyms--><ref name="JSON-P">{{cite web |url=http://www.json-p.org/ |title=Safer cross-domain Ajax with JSON-P/JSONP |work=JSON-P.org |accessdate=2011-10-30 |deadurl=yes |archiveurl=https://web.archive.org/web/20160304044218/http://www.json-p.org/ |archivedate=March 4, 2016}}</ref> that browsers would be able to enforce on script requests with a specific [[MIME]] type such as "application/json-p". If the response did not parse as strict JSONP, the browser could throw an error or just ignore the entire response. However, this approach was abandoned in favour of [[Cross-origin resource sharing|CORS]], and the correct MIME type for JSONP remains <code>application/javascript</code>.<ref>{{cite web |url=https://stackoverflow.com/a/3128948/569447 |first=Eli |last=Grey |title=Is this safe for providing JSONP? |work=stackoverflow.com |date=2010-06-27 |accessdate=2012-09-07 }}</ref>',
66 => false,
67 => '=== Callback name manipulation and reflected file download attack ===',
68 => 'Unsanitized callback names may be used to pass malicious data to clients, bypassing the restrictions associated with <code>application/json</code> content type, as demonstrated in reflected file download (RFD) attack from 2014.<ref>{{cite web | url=https://www.trustwave.com/Resources/SpiderLabs-Blog/Reflected-File-Download---A-New-Web-Attack-Vector/ | title=Reflected File Download - A New Web Attack Vector | publisher=TrustWave | date=2014 | accessdate=2015-03-25 | author=Oren Hafif}}</ref>',
69 => false,
70 => 'Insecure JSONP endpoints can be also injected with malicious data.<ref>{{cite web|url=https://securitycafe.ro/2017/01/18/practical-jsonp-injection/ |title=Practical JSONP injection}}</ref>',
71 => false,
72 => '==== Cross-site request forgery ====',
73 => 'Naive deployments of JSONP are subject to [[cross-site request forgery]] (CSRF or XSRF) attacks.<ref>{{cite web |url=http://jeremiahgrossman.blogspot.com/2006/01/advanced-web-attack-techniques-using.html |title=Advanced Web Attack Techniques using GMail |first=Jeremiah |last=Grossman |date=January 27, 2006 |accessdate=July 3, 2009}}</ref> Because the HTML <code><script></code> tag does not respect the [[same-origin policy]] in web browser implementations, a malicious page can request and obtain JSON data belonging to another site. This will allow the JSON-encoded data to be evaluated in the context of the malicious page, possibly divulging passwords or other sensitive data if the user is currently logged into the other site.',
74 => false,
75 => 'This is problematic only if the JSON-encoded data contains sensitive information which should not be disclosed to a third party, and the server depends on the [[same-origin policy]] of the browser to block the delivery of the data in the case of an unauthorized request. This security dependency on the browser's same-origin policy can be avoided by the server determining if the request is authorized and only putting the data on the wire if it is. Exclusive use of [[HTTP cookie|cookies]] for determining if a request is authorized should be avoided as it is subject to [[cross-site request forgery]].',
76 => false,
77 => '=== Rosetta Flash ===',
78 => 'Rosetta Flash is an exploitation technique that allows an attacker to exploit servers with a vulnerable JSONP endpoint by causing [[Adobe Flash Player]] to believe that an attacker-specified Flash applet originated on the vulnerable server. Flash Player implements [[same-origin policy]] allowing to make requests (with cookies) and receive responses from the hosting site. The applet can then send the retrieved data back to the attacker. This is a cross-origin exploit with an impact similar to embedding an arbitrary Flash applet in the vulnerable domain. The exploit uses an ActionScript payload compiled to an SWF file composed entirely of alphanumeric characters by crafting a [[zlib]] stream with a particular header and [[DEFLATE]] blocks with ad-hoc [[Huffman coding]]. The resulting alphanumeric-only SWF file is then used as the callback parameter of a JSONP call. High-profile sites such as Google, YouTube, Twitter, Yahoo!, Yandex, LinkedIn, eBay, Instagram and Tumblr were all vulnerable until July 2014.<ref>{{cite web|last1=Michele|first1=Spagnuolo|title=Abusing JSONP with Rosetta Flash|url=http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/|accessdate=July 20, 2014}}</ref> This vulnerability was discovered and published by Google security engineer Michele Spagnuolo<ref>{{cite web |url=https://www.google.com/about/appsecurity/research/ |title=Google - list of software vulnerabilities discovered or fixed by Googlers|accessdate=July 29, 2014}}</ref> and has [[Common Vulnerabilities and Exposures|CVE]] 2014-4671<ref>{{cite web |url=http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4671 |title=MITRE: CVE-2014-4671 |accessdate=July 29, 2014}}</ref> and CVE 2014-5333.<ref>{{cite web |url=http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-5333 |title=MITRE: CVE-2014-5333 |accessdate=August 21, 2014}}</ref> Adobe Flash Player release version 14.0.0.145, released on July 8, 2014, introduced stronger validation of Flash files,<ref>{{cite web |url=http://helpx.adobe.com/security/products/flash-player/apsb14-17.html |title=Adobe Security Bulletin APSB14-17 |accessdate=July 29, 2014}}</ref> and in version 14.0.0.176, released on August 12, 2014, finalized the fix,<ref>{{cite web |url=http://helpx.adobe.com/security/products/flash-player/apsb14-18.html |title=Adobe Security Bulletin APSB14-18 |accessdate=August 21, 2014}}</ref> preventing this exploit from working.',
79 => false,
80 => '== History ==',
81 => 'In July 2005, George Jempty suggested an optional variable assignment be prepended to JSON.<ref>{{cite web|url=http://htmatters.net/htm/1/2005/07/evaling-JSON.cfm |title=eval'ing JSON |date=July 19, 2005 |deadurl=yes |archiveurl=https://web.archive.org/web/20060212113746/http://htmatters.net/htm/1/2005/07/evaling-JSON.cfm |archivedate=February 12, 2006 }}</ref><ref>{{cite web |url=http://tech.groups.yahoo.com/group/json/message/82 |title=json: Message: Re: Comments |date=August 17, 2005}}</ref> The original proposal for JSONP, where the padding is a callback function, appears to have been made by Bob Ippolito in December 2005<ref>{{cite web |url=http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/ |work=from __future__ import * |title=Remote JSON - JSONP |publisher=Bob.pythonmac.org |date=December 5, 2005 |accessdate=September 8, 2008}}</ref> and is now used by many [[Web 2.0]] applications such as [[Dojo Toolkit]], [[Google Web Toolkit]] and [[Web service]]s.',
82 => false,
83 => '== See also ==',
84 => '* Cross-origin resource sharing (CORS)',
85 => '* [[Web Messaging|Cross-document messaging]]',
86 => false,
87 => '== References ==',
88 => '{{Reflist}}',
89 => false,
90 => '== External links ==',
91 => '* [http://www.vcarrer.com/2010/11/about-jsonp-in-javascript.html ''About JSONP in JavaScript'']',
92 => '* [https://code.google.com/p/jsonp-java/ server side filter wraps any response into a jsonp callback]{{snd}}done with jsonp-java source code',
93 => '* [http://quaxio.com/jsonp_handcrafted_flash_files/ Potential security issues related to JSONP]',
94 => '* [https://datatables.net/examples/server_side/jsonp.html JSONP data source for remote domains]'
] |
New page wikitext, pre-save transformed (new_pst ) | ''''JSONP''', i.e. [http://www.json.org/ JSON] with padding, proposed by Bob Ippolito,<ref>{{Cite web|url=http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/|title=Remote JSON - JSONP|last=Ippolito|first=Bob|date=|website=bob.ippoli.to|language=en|archive-url=|archive-date=|dead-url=|access-date=2017-02-10}}</ref> is used to request data from a server residing in a different domain than the client. This enables sharing of data bypassing [[same-origin policy]]. The policy disallows running [[JavaScript]] to read media [[Document Object Model|DOM]] elements or [[XMLHttpRequest|XHR]] data fetched from outside the page's origin. The aggregation of the site's scheme, port number and host name identifies as its origin. Due to inherent insecurities JSONP is being replaced by [[Cross-Origin Resource Sharing|CORS]].
== How JSONP works ==
The HTML <code><script></code> element is allowed to execute content retrieved from foreign origins. Services replying with pure JSON data were not able to share the data across domain before the adoption of CORS. For example, a request to a foreign service <code><nowiki>http://server.example.com/Users/1234</nowiki></code> may return a record for a person Foo in the JSON format, which, by definition, conforms to Javascript's object initializer syntax.
<source lang="html4strict" line="1">
{
"Name": "Foo",
"Id": 192.168.73.96,
"Rank": 7
}
</source>
Attempts to use the data across domain will result in a Javascript error.
<source lang="html4strict" line="1">
<script type="application/javascript"
src="http://server.example.com/Users/1234">
</script>
</source>
The browser will download the <code><script></code> file, evaluate its contents, mis-interpret the raw JSON data as a [[JavaScript syntax#Compound statements|block]], and throw a syntax error. Even if the data was interpreted as a JavaScript object literal, it could not be accessed by JavaScript running in the browser, since without a variable assignment, object literals are inaccessible.
In the JSONP usage pattern, the URL request pointed to by the <code>src</code> attribute in the <code><script></code> element returns JSON data, with JavaScript code (usually a function call) wrapped around it. This "wrapped payload" is then interpreted by the browser. In this way, a function that is already defined in the JavaScript environment can manipulate the JSON data. A typical JSONP request and response are shown below.
The function call to parseResponse() is the "P" of JSONP—the "padding" around the pure JSON, or according to some<ref>{{cite web|url=http://epimorph-pubx1.appspot.com/help.html |title=Experimental RDF result set to JSON translator |accessdate=February 20, 2012 |deadurl=yes |archiveurl=https://web.archive.org/web/20141115070803/http://epimorph-pubx1.appspot.com/help.html |archivedate=November 15, 2014 }}</ref> the "prefix".
Note that for JSONP to work, a server must reply with a response that includes the JSONP function. JSONP does not work with JSON-formatted results. The JSONP function invocation that gets sent back, and the payload that the function receives, must be agreed-upon by the client and server.
By convention, the server providing the JSON data offers the requesting website to name the JSONP function, typically using the name jsonp or [[callback (computer programming)|callback]] as the named query parameter field name, in its request to the server, e.g.,
<source lang="html4strict">
<script type="application/javascript"
src="http://server.example.com/Users/1234?callback=parseResponse">
</script>
</source>
In this example, the received payload would be:
<source lang="javascript">
parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});
</source>
== Script element injection ==
JSONP makes sense only when used with a script element. For each new JSONP request, the browser must add a new <code><script></code> element, or reuse an existing one. The former option—adding a new script element—is done via dynamic DOM manipulation, and is known as ''script element injection''. The <code><script></code> element is injected into the HTML DOM, with the URL of the desired JSONP endpoint set as the "src" attribute. This dynamic ''script element injection'' is usually done by a JavaScript helper library. [[jQuery]] and other frameworks have JSONP helper functions; there are also standalone options.<ref>{{cite web |url=http://pastebin.com/ADxHdCnB|title=example jsonp library on pastebin}}</ref><ref>{{cite web |url=https://github.com/robertodecurnex/J50Npi/|title=Basic JSONP helper (pure JS)}}</ref><ref>{{cite web |url=http://api.jquery.com/jQuery.getJSON/|title=jQuery's $.getJSON utility}}</ref>
An example of using jQuery to ''dynamically inject'' script element for a JSONP call looks like this:
<source lang="html4strict" line="1">
$.getScript("http://server.example.com/Users/192.168.73.96?callback=parseResponse");
</source>
After the element is injected, the browser evaluates the element, and performs an HTTP GET on the src URL, retrieving the content. Then the browser evaluates the return payload as JavaScript. This is typically a function invocation.
In that way, the use of JSONP can be said to ''allow browser pages to work around the [[same-origin policy]] via script element injection.''
The script runs within the scope of the including page and, as such, is still subject to cross-domain restrictions relative to the domain of the including page. This means that a web page cannot, for example, load a library hosted on another site via JSONP and then make XMLHttpRequest requests to that site (unless [[cross-origin resource sharing]] (CORS) is supported), although one could use such a library to make XMLHttpRequests to one's own site.
== Cross-domain requests using helper same-domain service ==
The JavaScript same-origin policy normally prevents browsers from reading responses to [[AJAX]] requests sent to a different domain (newer browsers that support [[Cross-Origin Resource Sharing|CORS]] allow relaxing this constraint with the foreign service's consent). A cooperating same-domain service can relay browser requests to a foreign server and respond with the foreign server's responses. This presents an alternative way of sharing data across domains where browsers do not regard CORS. (Malicious servers can steal web UI origins and lure unsuspecting users to visit the fake web UI origins).
== Security concerns ==
=== Untrusted third-party code ===
Including script tags from remote servers allows the remote servers to inject ''any'' content into a website. If the remote servers have vulnerabilities that allow JavaScript injection, the page served from the original server is exposed to an increased risk. If an attacker can inject any JavaScript into the original web page, then that code can retrieve additional JavaScript from any domain, bypassing [[same-origin policy]].<ref>{{cite web | url=https://www.blackhat.com/docs/eu-14/materials/eu-14-Hayak-Same-Origin-Method-Execution-Some-Exploiting-A-Callback-For-Same-Origin-Policy-Bypass.pdf | title=Same Origin Method Execution | date=2014-10-17 | accessdate=2014-10-22 | author=Ben Hayak}}</ref> The Content Security Policy HTTP Header lets web sites tell web browsers which domain scripts may be included from.
An effort was undertaken around 2011 to define a safer strict subset definition for JSONP<!--Is JSON-P important here? Seems to be synonyms--><ref name="JSON-P">{{cite web |url=http://www.json-p.org/ |title=Safer cross-domain Ajax with JSON-P/JSONP |work=JSON-P.org |accessdate=2011-10-30 |deadurl=yes |archiveurl=https://web.archive.org/web/20160304044218/http://www.json-p.org/ |archivedate=March 4, 2016}}</ref> that browsers would be able to enforce on script requests with a specific [[MIME]] type such as "application/json-p". If the response did not parse as strict JSONP, the browser could throw an error or just ignore the entire response. However, this approach was abandoned in favour of [[Cross-origin resource sharing|CORS]], and the correct MIME type for JSONP remains <code>application/javascript</code>.<ref>{{cite web |url=https://stackoverflow.com/a/3128948/569447 |first=Eli |last=Grey |title=Is this safe for providing JSONP? |work=stackoverflow.com |date=2010-06-27 |accessdate=2012-09-07 }}</ref>
=== Callback name manipulation and reflected file download attack ===
Unsanitized callback names may be used to pass malicious data to clients, bypassing the restrictions associated with <code>application/json</code> content type, as demonstrated in reflected file download (RFD) attack from 2014.<ref>{{cite web | url=https://www.trustwave.com/Resources/SpiderLabs-Blog/Reflected-File-Download---A-New-Web-Attack-Vector/ | title=Reflected File Download - A New Web Attack Vector | publisher=TrustWave | date=2014 | accessdate=2015-03-25 | author=Oren Hafif}}</ref>
Insecure JSONP endpoints can be also injected with malicious data.<ref>{{cite web|url=https://securitycafe.ro/2017/01/18/practical-jsonp-injection/ |title=Practical JSONP injection}}</ref>
==== Cross-site request forgery ====
Naive deployments of JSONP are subject to [[cross-site request forgery]] (CSRF or XSRF) attacks.<ref>{{cite web |url=http://jeremiahgrossman.blogspot.com/2006/01/advanced-web-attack-techniques-using.html |title=Advanced Web Attack Techniques using GMail |first=Jeremiah |last=Grossman |date=January 27, 2006 |accessdate=July 3, 2009}}</ref> Because the HTML <code><script></code> tag does not respect the [[same-origin policy]] in web browser implementations, a malicious page can request and obtain JSON data belonging to another site. This will allow the JSON-encoded data to be evaluated in the context of the malicious page, possibly divulging passwords or other sensitive data if the user is currently logged into the other site.
This is problematic only if the JSON-encoded data contains sensitive information which should not be disclosed to a third party, and the server depends on the [[same-origin policy]] of the browser to block the delivery of the data in the case of an unauthorized request. This security dependency on the browser's same-origin policy can be avoided by the server determining if the request is authorized and only putting the data on the wire if it is. Exclusive use of [[HTTP cookie|cookies]] for determining if a request is authorized should be avoided as it is subject to [[cross-site request forgery]].
=== Rosetta Flash ===
Rosetta Flash is an exploitation technique that allows an attacker to exploit servers with a vulnerable JSONP endpoint by causing [[Adobe Flash Player]] to believe that an attacker-specified Flash applet originated on the vulnerable server. Flash Player implements [[same-origin policy]] allowing to make requests (with cookies) and receive responses from the hosting site. The applet can then send the retrieved data back to the attacker. This is a cross-origin exploit with an impact similar to embedding an arbitrary Flash applet in the vulnerable domain. The exploit uses an ActionScript payload compiled to an SWF file composed entirely of alphanumeric characters by crafting a [[zlib]] stream with a particular header and [[DEFLATE]] blocks with ad-hoc [[Huffman coding]]. The resulting alphanumeric-only SWF file is then used as the callback parameter of a JSONP call. High-profile sites such as Google, YouTube, Twitter, Yahoo!, Yandex, LinkedIn, eBay, Instagram and Tumblr were all vulnerable until July 2014.<ref>{{cite web|last1=Michele|first1=Spagnuolo|title=Abusing JSONP with Rosetta Flash|url=http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/|accessdate=July 20, 2014}}</ref> This vulnerability was discovered and published by Google security engineer Michele Spagnuolo<ref>{{cite web |url=https://www.google.com/about/appsecurity/research/ |title=Google - list of software vulnerabilities discovered or fixed by Googlers|accessdate=July 29, 2014}}</ref> and has [[Common Vulnerabilities and Exposures|CVE]] 2014-4671<ref>{{cite web |url=http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4671 |title=MITRE: CVE-2014-4671 |accessdate=July 29, 2014}}</ref> and CVE 2014-5333.<ref>{{cite web |url=http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-5333 |title=MITRE: CVE-2014-5333 |accessdate=August 21, 2014}}</ref> Adobe Flash Player release version 14.0.0.145, released on July 8, 2014, introduced stronger validation of Flash files,<ref>{{cite web |url=http://helpx.adobe.com/security/products/flash-player/apsb14-17.html |title=Adobe Security Bulletin APSB14-17 |accessdate=July 29, 2014}}</ref> and in version 14.0.0.176, released on August 12, 2014, finalized the fix,<ref>{{cite web |url=http://helpx.adobe.com/security/products/flash-player/apsb14-18.html |title=Adobe Security Bulletin APSB14-18 |accessdate=August 21, 2014}}</ref> preventing this exploit from working.
== History ==
In July 2005, George Jempty suggested an optional variable assignment be prepended to JSON.<ref>{{cite web|url=http://htmatters.net/htm/1/2005/07/evaling-JSON.cfm |title=eval'ing JSON |date=July 19, 2005 |deadurl=yes |archiveurl=https://web.archive.org/web/20060212113746/http://htmatters.net/htm/1/2005/07/evaling-JSON.cfm |archivedate=February 12, 2006 }}</ref><ref>{{cite web |url=http://tech.groups.yahoo.com/group/json/message/82 |title=json: Message: Re: Comments |date=August 17, 2005}}</ref> The original proposal for JSONP, where the padding is a callback function, appears to have been made by Bob Ippolito in December 2005<ref>{{cite web |url=http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/ |work=from __future__ import * |title=Remote JSON - JSONP |publisher=Bob.pythonmac.org |date=December 5, 2005 |accessdate=September 8, 2008}}</ref> and is now used by many [[Web 2.0]] applications such as [[Dojo Toolkit]], [[Google Web Toolkit]] and [[Web service]]s.
== See also ==
* Cross-origin resource sharing (CORS)
* [[Web Messaging|Cross-document messaging]]
== References ==
{{Reflist}}
== External links ==
* [http://www.vcarrer.com/2010/11/about-jsonp-in-javascript.html ''About JSONP in JavaScript'']
* [https://code.google.com/p/jsonp-java/ server side filter wraps any response into a jsonp callback]{{snd}}done with jsonp-java source code
* [http://quaxio.com/jsonp_handcrafted_flash_files/ Potential security issues related to JSONP]
* [https://datatables.net/examples/server_side/jsonp.html JSONP data source for remote domains]
[[Category:Ajax (programming)]]
[[Category:JSON]]' |