JSONP

Last updated

JSONP, or JSON-P (JSON with Padding), is a historical JavaScript technique for requesting data by loading a <script> element, [1] which is an element intended to load ordinary JavaScript. It was proposed by Bob Ippolito in 2005. [2] JSONP enables sharing of data bypassing same-origin policy, which disallows running JavaScript code to read media DOM elements or XMLHttpRequest data fetched from outside the page's originating site. The originating site is indicated by a combination of URI scheme, hostname, and port number.

Contents

JSONP is vulnerable to the data source replacing the innocuous function call with malicious code, which is why it has been superseded by cross-origin resource sharing (available since 2009 [3] ) in modern applications.

Functionality

The HTML <script> element is generally allowed to execute JavaScript code retrieved from foreign origins. Services replying with pure JSON data, however, were not able to share data from foreign origins before the adoption of CORS (Cross-origin resource sharing).

For example, a request to a foreign service http://server.example.com/Users/1234 may return a record for a person named Clem in the JSON format. JSON syntax is consistent with JavaScript's object syntax.

{"Name":"Clem","Id":1234,"Rank":7}

Without support for CORS, an attempt to use the data across domains results in a JavaScript error.

<scripttype="application/javascript"src="http://server.example.com/Users/1234"></script>

The browser will download the <script> file, evaluate its contents, misinterpret the raw JSON data as a block, and throw a syntax error. Even if the data were 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 src attribute in the <script> 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" or "prefix" around the pure JSON. [4] 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 as the named query-string parameter, in its request to the server: <script src="<nowiki>http://server.example.com/Users/1234?callback=parseResponse</nowiki>"></script>.

In this example, the received payload would be:

parseResponse({"Name":"Clem","Id":1234,"Rank":7});

Script element injection

JSONP makes sense only when used with a script element. For each new JSONP request, the browser must add a new <script> 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 <script> 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.

An example of using jQuery to dynamically inject script element for a JSONP call looks like this:

$.getScript("http://server.example.com/Users/192.168.73.96?callback=parseResponse");

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 allow browser pages to work around the same-origin policy via script element injection. [5]

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.

Security concerns

Untrusted third-party code

Including script elements 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 the same-origin policy. [6] 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 [1] 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 favor of CORS, and the correct MIME type for JSONP remains application/javascript. [7]

Whitespace differences

JSONP carried the same problems as resolving JSON with eval(): both interpret the JSON text as JavaScript, which meant differences in handling U+2028 (Line Separator) and U+2029 (Paragraph Separator) from JSON proper. This made some JSON strings non-legal in JSONP; servers serving JSONP had to escape these characters prior to transmission. [8] This issue has now been rectified in ES2019. [9]

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 application/json content type, as demonstrated in reflected file download (RFD) attack from 2014. [10]

Insecure JSONP endpoints can be also injected with malicious data. [11]

Cross-site request forgery

Naive deployments of JSONP are subject to cross-site request forgery (CSRF or XSRF) attacks. [12] Because the HTML <script> element 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.

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 one 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, GitHub, Instagram, and Tumblr were all vulnerable until July 2014. [13] This vulnerability was initially discovered by Erling and Alok Menghrajani, with a public presentation at a security conference. The exploitation of the vulnerability was subsequently improved by Gábor Molnár. Google security engineer Michele Spagnuolo coined the term [14] and has CVE - 2014-4671 [15] and CVE- 2014-5333. [16] Adobe Flash Player release version 14.0.0.145, released on July 8, 2014, introduced stronger validation of Flash files, [17] and in version 14.0.0.176, released on August 12, 2014, finalized the fix, [18] preventing this exploit from working.

Prior to Adobe's fix, websites could protect themselves by prepending an empty JavaScript comment (/**/) or even just a newline as the first bytes of the JSONP response.

History

In July 2005, George Jempty suggested an optional variable assignment be prepended to JSON. [19] [20] The original proposal for JSONP, where the padding is a callback function, appears to have been made by Bob Ippolito in December 2005 [21] and is now used by many Web 2.0 applications such as Dojo Toolkit and Google Web Toolkit.

See also

Related Research Articles

<span class="mw-page-title-main">JavaScript</span> High-level programming language

JavaScript, often abbreviated as JS, is a programming language that is one of the core technologies of the World Wide Web, alongside HTML and CSS. As of 2023, 98.7% of websites use JavaScript on the client side for webpage behavior, often incorporating third-party libraries. All major web browsers have a dedicated JavaScript engine to execute the code on users' devices.

Cross-site scripting (XSS) is a type of security vulnerability that can be found in some web applications. XSS attacks enable attackers to inject client-side scripts into web pages viewed by other users. A cross-site scripting vulnerability may be used by attackers to bypass access controls such as the same-origin policy. Cross-site scripting carried out on websites accounted for roughly 84% of all security vulnerabilities documented by Symantec up until 2007. XSS effects vary in range from petty nuisance to significant security risk, depending on the sensitivity of the data handled by the vulnerable site and the nature of any security mitigation implemented by the site's owner network.

<span class="mw-page-title-main">Adobe ColdFusion</span> Rapid Web app development platform

Adobe ColdFusion is a commercial rapid web-application development computing platform created by J. J. Allaire in 1995. ColdFusion was originally designed to make it easier to connect simple HTML pages to a database. By version 2 (1996) it had become a full platform that included an IDE in addition to a full scripting language.

Code injection is the exploitation of a computer bug that is caused by processing invalid data. The injection is used by an attacker to introduce code into a vulnerable computer program and change the course of execution. The result of successful code injection can be disastrous, for example, by allowing computer viruses or computer worms to propagate.

<span class="mw-page-title-main">JSON</span> Open standard file format and data interchange

JSON is an open standard file format and data interchange format that uses human-readable text to store and transmit data objects consisting of attribute–value pairs and arrays. It is a common data format with diverse uses in electronic data interchange, including that of web applications with servers.

<span class="mw-page-title-main">XMLHttpRequest</span> Web API to transfer data between a web browser and a web server

XMLHttpRequest (XHR) is a JavaScript class containing methods to asynchronously transmit HTTP requests from a web browser to a web server. The methods allow a browser-based application to make a fine-grained server call and store the results in XMLHttpRequest's responseText attribute. The XMLHttpRequest class is a component of Ajax programming. Prior to Ajax, an HTML form needed to be completely sent to the server followed by a complete browser page refresh.

Ajax is a set of web development techniques that uses various web technologies on the client-side to create asynchronous web applications. With Ajax, web applications can send and retrieve data from a server asynchronously without interfering with the display and behaviour of the existing page. By decoupling the data interchange layer from the presentation layer, Ajax allows web pages and, by extension, web applications, to change content dynamically without the need to reload the entire page. In practice, modern implementations commonly utilize JSON instead of XML.

<span class="mw-page-title-main">Same-origin policy</span> Security measure for client-side scripting

In computing, the same-origin policy (SOP) is an important concept in the web application security model. Under the policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. An origin is defined as a combination of URI scheme, host name, and port number. This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page through that page's Document Object Model (DOM).

Comet is a web application model in which a long-held HTTPS request allows a web server to push data to a browser, without the browser explicitly requesting it. Comet is an umbrella term, encompassing multiple techniques for achieving this interaction. All these methods rely on features included by default in browsers, such as JavaScript, rather than on non-default plugins. The Comet approach differs from the original model of the web, in which a browser requests a complete web page at a time.

The Prototype JavaScript Framework is a JavaScript framework created by Sam Stephenson in February 2005 as part of Ajax support in Ruby on Rails. It is implemented as a single file of JavaScript code, usually named prototype.js. Prototype is distributed standalone, but also as part of larger projects, such as Ruby on Rails, script.aculo.us and Rico. As of March 2021, according to w3techs, Prototype is used by 0.6% of all websites.

<span class="mw-page-title-main">YUI Library</span>

The Yahoo! User Interface Library (YUI) is a discontinued open-source JavaScript library for building richly interactive web applications using techniques such as Ajax, DHTML, and DOM scripting. YUI includes several core CSS resources. It is available under a BSD License. Development on YUI began in 2005 and Yahoo! properties such as My Yahoo! and the Yahoo! front page began using YUI in the summer of that year. YUI was released for public use in February 2006. It was actively developed by a core team of Yahoo! engineers.

jQuery is a JavaScript library designed to simplify HTML DOM tree traversal and manipulation, as well as event handling, CSS animation, and Ajax. It is free, open-source software using the permissive MIT License. As of August 2022, jQuery is used by 77% of the 10 million most popular websites. Web analysis indicates that it is the most widely deployed JavaScript library by a large margin, having at least 3 to 4 times more usage than any other JavaScript library.

DNS rebinding is a method of manipulating resolution of domain names that is commonly used as a form of computer attack. In this attack, a malicious web page causes visitors to run a client-side script that attacks machines elsewhere on the network. In theory, the same-origin policy prevents this from happening: client-side scripts are only allowed to access content on the same host that served the script. Comparing domain names is an essential part of enforcing this policy, so DNS rebinding circumvents this protection by abusing the Domain Name System (DNS).

<span class="mw-page-title-main">Clickjacking</span> Malicious technique of tricking a Web user

Clickjacking is a malicious technique of tricking a user into clicking on something different from what the user perceives, thus potentially revealing confidential information or allowing others to take control of their computer while clicking on seemingly innocuous objects, including web pages.

In data sanitization, HTML sanitization is the process of examining an HTML document and producing a new HTML document that preserves only whatever tags are designated "safe" and desired. HTML sanitization can be used to protect against attacks such as cross-site scripting (XSS) by sanitizing any HTML code submitted by a user.

Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be accessed from another domain outside the domain from which the first resource was served.

Cross-site request forgery, also known as one-click attack or session riding and abbreviated as CSRF or XSRF, is a type of malicious exploit of a website or web application where unauthorized commands are submitted from a user that the web application trusts. There are many ways in which a malicious website can transmit such commands; specially-crafted image tags, hidden forms, and JavaScript fetch or XMLHttpRequests, for example, can all work without the user's interaction or even knowledge. Unlike cross-site scripting (XSS), which exploits the trust a user has for a particular site, CSRF exploits the trust that a site has in a user's browser. In a CSRF attack, an innocent end user is tricked by an attacker into submitting a web request that they did not intend. This may cause actions to be performed on the website that can include inadvertent client or server data leakage, change of session state, or manipulation of an end user's account.

Content Security Policy (CSP) is a computer security standard introduced to prevent cross-site scripting (XSS), clickjacking and other code injection attacks resulting from execution of malicious content in the trusted web page context. It is a Candidate Recommendation of the W3C working group on Web Application Security, widely supported by modern web browsers. CSP provides a standard method for website owners to declare approved origins of content that browsers should be allowed to load on that website—covered types are JavaScript, CSS, HTML frames, web workers, fonts, images, embeddable objects such as Java applets, ActiveX, audio and video files, and other HTML5 features.

Browser security is the application of Internet security to web browsers in order to protect networked data and computer systems from breaches of privacy or malware. Security exploits of browsers often use JavaScript, sometimes with cross-site scripting (XSS) with a secondary payload using Adobe Flash. Security exploits can also take advantage of vulnerabilities that are commonly exploited in all browsers.

References

  1. 1 2 "Safer cross-domain Ajax with JSON-P/JSONP". JSON-P.org. Archived from the original on 4 March 2016. Retrieved 30 October 2011.
  2. Ippolito, Bob (5 December 2005). "Remote JSON - JSONP". Bob Ippolito on Haskell, Python, Erlang, JavaScript, etc. Archived from the original on 8 June 2012. Retrieved 10 February 2017.
  3. "Cross-Origin Resource Sharing". Can I use... Retrieved 4 May 2020.
  4. "Experimental RDF result set to JSON translator". Archived from the original on 15 November 2014. Retrieved 20 February 2012.
  5. "So how does JSONP really work? Some simple examples". Jason Schock. 5 February 2013. Retrieved 26 December 2021.
  6. Ben Hayak (17 October 2014). "Same Origin Method Execution" (PDF). Retrieved 22 October 2014.
  7. Grey, Eli (27 June 2010). "Is this safe for providing JSONP?". stackoverflow.com. Retrieved 7 September 2012.
  8. "JSON: The JavaScript subset that isn't". Magnus Holm. Archived from the original on 13 May 2012. Retrieved 16 May 2011.
  9. "Subsume JSON (a.k.a. JSON ⊂ ECMAScript)". GitHub . 24 October 2022. Retrieved 24 October 2022.
  10. Oren Hafif (2014). "Reflected File Download - A New Web Attack Vector". TrustWave. Retrieved 25 March 2015.
  11. "Practical JSONP injection". 18 January 2017.
  12. Grossman, Jeremiah (27 January 2006). "Advanced Web Attack Techniques using GMail" . Retrieved 3 July 2009.
  13. Michele, Spagnuolo. "Abusing JSONP with Rosetta Flash". Archived from the original on 21 July 2014. Retrieved 20 July 2014.
  14. "Google - list of software vulnerabilities discovered or fixed by Googlers" . Retrieved 29 July 2014.
  15. "MITRE: CVE-2014-4671" . Retrieved 29 July 2014.
  16. "MITRE: CVE-2014-5333" . Retrieved 21 August 2014.
  17. "Adobe Security Bulletin APSB14-17" . Retrieved 29 July 2014.
  18. "Adobe Security Bulletin APSB14-18" . Retrieved 21 August 2014.
  19. "eval'ing JSON". 19 July 2005. Archived from the original on 12 February 2006.
  20. "json: Message: Re: Comments". 17 August 2005.
  21. "Remote JSON - JSONP". from __future__ import *. Bob.pythonmac.org. 5 December 2005. Archived from the original on 4 December 2009. Retrieved 8 September 2008.