{"id":3712,"date":"2015-09-05T19:36:29","date_gmt":"2015-09-06T00:36:29","guid":{"rendered":"http:\/\/www.filecloud.com\/blog\/?page_id=3712"},"modified":"2022-04-21T07:43:19","modified_gmt":"2022-04-21T12:43:19","slug":"using-jsonp-for-cross-domain-requests","status":"publish","type":"page","link":"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/","title":{"rendered":"Using JSONP and CORS for Cross Domain Requests | FileCloud"},"content":{"rendered":"<h1>Using JSONP for cross domain requests<\/h1>\n<p dir=\"ltr\">It is often seen that developers are not confined to the limits of their own domains. When you make requests through JavaScript across domains, the browser prevents the request from going through citing the absence of an \u2018Access-Control-Allow-Origin\u2019 header. This is termed as the \u2018Same Origin Policy\u2019 of browsers which allows scripts running on a domain to make requests to resources on the same domain only, comprising the same URI scheme, domain and host number. There are many ways around the same origin policy- ranging from routing the request through a web proxy to using CORS (Cross Origin Resource Sharing), but the most popular method is using JSONP.<\/p>\n<h2>What is JSONP?<\/h2>\n<p dir=\"ltr\">JSONP simply refers to \u201cJSON with padding\u201d. It is essentially a JSON response wrapped around a callback function that is specified in the URL. For instance, the following a JSON response.<\/p>\n<p>{\u00a0\u201cusername\u201d: \u201csdaityari\u201d,\u00a0\u201cname\u201d: \u201cShaumik Daityari\u201d}<\/p>\n<p dir=\"ltr\">The same response with a callback function specified as processData is as follows.<\/p>\n<p dir=\"ltr\">\u00a0processData({ \u201cusername\u201d: \u201csdaityari\u201d, \u201cname\u201d: \u201cShaumik Daityari\u201d})<\/p>\n<h2>How does JSONP help in working around the same origin policy?<\/h2>\n<p dir=\"ltr\">As browsers don\u2019t allow requests to other domains, how then do we add external files to CDNs (Content Delivery Networks) to speed up page loading and still get them to work? The hidden agenda is here is the fact that these files are present under the src attribute of &lt;script&gt; tags. This leads to a conclusion that anything under the &lt;script&gt; tags is executed by the browser under the context of the current domain!<\/p>\n<p dir=\"ltr\">Using the same idea, we supply a callback function, generally as a GET variable, to the src in the &lt;script&gt; tag, and we get a response of a JSON wrapped with the callback function. That essentially means that the callback function is executed with the JSON response as arguments. That helps in working around applications just like we did in the case of AJAX.<\/p>\n<p dir=\"ltr\">In the JSONP example provided, we would execute the function like the following-<\/p>\n<p dir=\"ltr\">\u00a0&lt;script src=\u201dhttp:\/\/www.example.com\/json_data?callback=processData\u201d&gt;&lt;\/script&gt;<\/p>\n<p dir=\"ltr\">By doing so, processData would be executed with the given arguments.<\/p>\n<h3>Why would this not work if it was returning just JSON?<\/h3>\n<p dir=\"ltr\">In place of a JSON response padded within a function, if the server just returned a JSON, the data would not get executed, instead raising a Syntax Error. You could emulate a response by pasting some JSON into your JavaScript console.<\/p>\n<h2>When can it go wrong?<\/h2>\n<p dir=\"ltr\">In the example above, the data that was returned through JSON was not so sensitive. It just contained the username and name. However, imagine an ecommerce site which stores credit card details as a part of your profile. Let\u2019s assume the following request being made-<\/p>\n<p dir=\"ltr\">&lt;script src=\u201d<a href=\"http:\/\/api.myecommercesite.com\/profile?callback=processData\" class=\"broken_link\">http:\/\/api.myecommercesite.com\/profile?callback=processData<\/a>\u201d&gt;&lt;\/script&gt;<\/p>\n<p dir=\"ltr\">The website <a href=\"http:\/\/api.myecommercesite.com\" class=\"broken_link\">api.myecommercesite.com<\/a> would return the following response irrecpective of the website that requested the information.<\/p>\n<p dir=\"ltr\">\u00a0processData({<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0\u201cname\u201d: \u201cShaumik Daityari\u201d,<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0\u201ccard_no\u201d: \u201cxxxx xxxx xxxx xxxx\u201d,<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0\u201cexpiry_date\u201d: \u201cxx-xxxx\u201d<\/p>\n<p dir=\"ltr\">\u00a0});<\/p>\n<h3>How does an attacker use it to get your data?<\/h3>\n<p dir=\"ltr\">In the ideal case, this data is received by the intended website and used accordingly. However, let\u2019s say that a malicious site, <a href=\"http:\/\/www.attacker.com\">www.attacker.com<\/a>, gets wind of the information and tricks you into redirecting you to their server.<\/p>\n<p dir=\"ltr\">Basically, you are browsing <a href=\"http:\/\/www.attacker.com\">www.attacker.com<\/a> and you are asked to click on something. Their server then sends the same response and since you are logged into the ecommerce site, data containing your information is returned. (There are other non-JSONP related security checks which can prevent this from happening, but let\u2019s assume there were no other security measures to prevent this from happening.)<\/p>\n<p dir=\"ltr\">Once a malicious site gets hold of the sensitive data, it can process the data on the context of the site, and therefore do whatsoever it wishes with the data, most probably storing it in their own servers for later use. Not only this, a malicious site can also get hold of your cookies which contain vital information that a website uses to track your progress on its site.<\/p>\n<h2>Using JSONP safely<\/h2>\n<p dir=\"ltr\">The reason JSONP got so popular is the ease of use and implementation. All you need is a callback and you are done. Therefore, there are many security concerns which need to be taken care of while using this technique.<\/p>\n<h3>Sanitize callback<\/h3>\n<p dir=\"ltr\">This is one little thing that can lead to dangerous consequences. In fact, many tutorials talking about the security in the JSONP method fail to get this one right. In PHP, you would generally execute the following.<\/p>\n<p dir=\"ltr\">\u00a0echo $_GET[\u201ccallback\u201d] . \u201c(\u201c . json_encode($my_data) . \u201c);\u201d;<\/p>\n<p dir=\"ltr\">In addition to that, vulnerabilities in JSONP have also been identified through a term called flash injection.<\/p>\n<p dir=\"ltr\">The right way, as explained by <a href=\"http:\/\/www.metaltoad.com\/blog\/using-jsonp-safely\">Dylan Tack<\/a> on his blog, is to use appropriate headers to manipulate the output in case the callback is being used for an XSS attack. He uses the following code-<\/p>\n<p dir=\"ltr\">function generate_jsonp($data) {<\/p>\n<p dir=\"ltr\">\u00a0if (preg_match(\u2018\/\\W\/\u2019, $_GET[\u2018callback\u2019])) {<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0\/\/ if $_GET[\u2018callback\u2019] contains a non-word character,<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0\/\/ this could be an XSS attack.<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0header(\u2018HTTP\/1.1 400 Bad Request\u2019);<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0exit();<\/p>\n<p dir=\"ltr\">\u00a0}<\/p>\n<p dir=\"ltr\">\u00a0header(\u2018Content-type: application\/javascript; charset=utf-8\u2019);<\/p>\n<p dir=\"ltr\">\u00a0print sprintf(\u2018%s(%s);\u2019, $_GET[\u2018callback\u2019], json_encode($data));<\/p>\n<p dir=\"ltr\">}<\/p>\n<h3>Full trust on a different domain<\/h3>\n<p dir=\"ltr\">Using the JSONP requires that you trust the remote domain fully. This essentially means that if, for some reason, the functionality remote domain breaks, your service breaks too. It remains your decision, however, whether you want to depend on a third party service.<\/p>\n<p dir=\"ltr\">Moreover, as we are using it under script tags, it is difficult to catch errors within it and error handling changes from browser to browser, making it difficult to manage a proper structure.<\/p>\n<h3>User Authentication<\/h3>\n<p dir=\"ltr\">For argument\u2019s sake, a possible way to login a user into a remote site using only JSONP would involve sending the username and password as GET variables (since that is the only way HTTP requests can get you the data in a script tag). It is an unsafe method of authentication and therefore, should be avoided.<\/p>\n<p dir=\"ltr\">For the purpose of user authentication, it\u2019s favourable that you follow the general workflow of OAuth- redirect to parent website, authenticate the user and on successful authentication, generate and share a token.<\/p>\n<h3>Using CSRF tokens for write operations<\/h3>\n<p dir=\"ltr\">In case you are using the JSONP technique to write data to your server (whether it\u2019s create or update), you must know that JSONP uses GET, which is not secure. In order to make sure that everything goes according to plan, you could issue a token within the headers of every request. A token needs to be generated for every user who is authenticated using the step above.<\/p>\n<p dir=\"ltr\">That being said, there are far better options considering security during writes, updates or deletes and you should follow them rather than finding workarounds with JSONP, which should ideally be used for reads only.<\/p>\n<h2>Looking forward- using CORS (Cross Origin Resource Sharing)<\/h2>\n<p dir=\"ltr\">We have seen a few use cases of JSONP and all of them can be achieved by the web proxy method too. Although the JSONP technique remains popular, the vulnerabilities in it make it a headache to implement in complex situations. CORS has been gaining popularity steadily as its support in major browsers continues to grow, and it\u2019s taking over the uses of JSONP.<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0request = new XDomainRequest();<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0request.open(method, url);<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0request.onload = function() {<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0\u00a0\u00a0callback(req.responseText);<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0};<\/p>\n<p dir=\"ltr\">\u00a0\u00a0\u00a0request.send(data);<\/p>\n<h3>How does CORS work?<\/h3>\n<p dir=\"ltr\">The CORS process adds new HTTP headers to the request, which allows the server to serve resources, but only to requests from known and trusted domains. This means that if <a href=\"http:\/\/www.attacker.com\">www.attacker.com<\/a> tries to access information from <a href=\"http:\/\/api.myecommercesite.com\" class=\"broken_link\">api.myecommercesite.com<\/a>, it would not be possible because <a href=\"http:\/\/api.myecommercesite.com\" class=\"broken_link\">api.myecommercesite.com<\/a> would not recognize <a href=\"http:\/\/www.attacker.com\">www.attacker.com<\/a>! For further information on CORS, you could head over the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/HTTP\/Access_control_CORS\">Mozilla Developer Network<\/a>.<\/p>\n<p dir=\"ltr\">The only drawback of CORS is the lack of support from older browsers and if you don\u2019t care about users with those old browsers, you should definitely go ahead and give CORS a try.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using JSONP for cross domain requests It is often seen that developers are not confined to the limits of their own domains. When you make requests through JavaScript across domains, the browser prevents the request from going through citing the absence of an \u2018Access-Control-Allow-Origin\u2019 header. This is termed as the \u2018Same Origin Policy\u2019 of browsers [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.13 (Yoast SEO v20.13) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using JSONP and CORS for Cross Domain Requests | FileCloud<\/title>\n<meta name=\"description\" content=\"Using JSONP and CORS for cross domain requests: It is a technique for fooling a web browser into performing cross-origin requests using a special script tag.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using JSONP and CORS for Cross Domain Requests | FileCloud\" \/>\n<meta property=\"og:description\" content=\"Using JSONP and CORS for cross domain requests: It is a technique for fooling a web browser into performing cross-origin requests using a special script tag.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/\" \/>\n<meta property=\"og:site_name\" content=\"FileCloud blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/tonidopage\" \/>\n<meta property=\"article:modified_time\" content=\"2022-04-21T12:43:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.filecloud.com\/blog\/wp-content\/uploads\/2023\/05\/FC-OG-image.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"551\" \/>\n\t<meta property=\"og:image:height\" content=\"289\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@getfilecloud\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/\",\"url\":\"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/\",\"name\":\"Using JSONP and CORS for Cross Domain Requests | FileCloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.filecloud.com\/blog\/#website\"},\"datePublished\":\"2015-09-06T00:36:29+00:00\",\"dateModified\":\"2022-04-21T12:43:19+00:00\",\"description\":\"Using JSONP and CORS for cross domain requests: It is a technique for fooling a web browser into performing cross-origin requests using a special script tag.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.filecloud.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using JSONP and CORS for Cross Domain Requests | FileCloud\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.filecloud.com\/blog\/#website\",\"url\":\"https:\/\/www.filecloud.com\/blog\/\",\"name\":\"FileCloud blog\",\"description\":\"Topics on Private cloud, On-Premises, Self-Hosted, Enterprise File Sync and Sharing\",\"publisher\":{\"@id\":\"https:\/\/www.filecloud.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.filecloud.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.filecloud.com\/blog\/#organization\",\"name\":\"FileCloud\",\"url\":\"https:\/\/www.filecloud.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.filecloud.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.filecloud.com\/blog\/wp-content\/uploads\/2016\/02\/filecloud_logo_comparison.jpg\",\"contentUrl\":\"https:\/\/www.filecloud.com\/blog\/wp-content\/uploads\/2016\/02\/filecloud_logo_comparison.jpg\",\"width\":155,\"height\":40,\"caption\":\"FileCloud\"},\"image\":{\"@id\":\"https:\/\/www.filecloud.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/tonidopage\",\"https:\/\/twitter.com\/getfilecloud\",\"https:\/\/www.linkedin.com\/company\/codelathe\",\"https:\/\/www.pinterest.com\/filecloud\/filecloud\/\",\"https:\/\/www.youtube.com\/channel\/UCbU5gTFdNCPESA5aGipFW6g\"]}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Using JSONP and CORS for Cross Domain Requests | FileCloud","description":"Using JSONP and CORS for cross domain requests: It is a technique for fooling a web browser into performing cross-origin requests using a special script tag.","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:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/","og_locale":"en_US","og_type":"article","og_title":"Using JSONP and CORS for Cross Domain Requests | FileCloud","og_description":"Using JSONP and CORS for cross domain requests: It is a technique for fooling a web browser into performing cross-origin requests using a special script tag.","og_url":"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/","og_site_name":"FileCloud blog","article_publisher":"https:\/\/www.facebook.com\/tonidopage","article_modified_time":"2022-04-21T12:43:19+00:00","og_image":[{"width":551,"height":289,"url":"https:\/\/www.filecloud.com\/blog\/wp-content\/uploads\/2023\/05\/FC-OG-image.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_site":"@getfilecloud","twitter_misc":{"Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/","url":"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/","name":"Using JSONP and CORS for Cross Domain Requests | FileCloud","isPartOf":{"@id":"https:\/\/www.filecloud.com\/blog\/#website"},"datePublished":"2015-09-06T00:36:29+00:00","dateModified":"2022-04-21T12:43:19+00:00","description":"Using JSONP and CORS for cross domain requests: It is a technique for fooling a web browser into performing cross-origin requests using a special script tag.","breadcrumb":{"@id":"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.filecloud.com\/blog\/using-jsonp-for-cross-domain-requests\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.filecloud.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using JSONP and CORS for Cross Domain Requests | FileCloud"}]},{"@type":"WebSite","@id":"https:\/\/www.filecloud.com\/blog\/#website","url":"https:\/\/www.filecloud.com\/blog\/","name":"FileCloud blog","description":"Topics on Private cloud, On-Premises, Self-Hosted, Enterprise File Sync and Sharing","publisher":{"@id":"https:\/\/www.filecloud.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.filecloud.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.filecloud.com\/blog\/#organization","name":"FileCloud","url":"https:\/\/www.filecloud.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.filecloud.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.filecloud.com\/blog\/wp-content\/uploads\/2016\/02\/filecloud_logo_comparison.jpg","contentUrl":"https:\/\/www.filecloud.com\/blog\/wp-content\/uploads\/2016\/02\/filecloud_logo_comparison.jpg","width":155,"height":40,"caption":"FileCloud"},"image":{"@id":"https:\/\/www.filecloud.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/tonidopage","https:\/\/twitter.com\/getfilecloud","https:\/\/www.linkedin.com\/company\/codelathe","https:\/\/www.pinterest.com\/filecloud\/filecloud\/","https:\/\/www.youtube.com\/channel\/UCbU5gTFdNCPESA5aGipFW6g"]}]}},"_links":{"self":[{"href":"https:\/\/www.filecloud.com\/blog\/wp-json\/wp\/v2\/pages\/3712"}],"collection":[{"href":"https:\/\/www.filecloud.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.filecloud.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.filecloud.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.filecloud.com\/blog\/wp-json\/wp\/v2\/comments?post=3712"}],"version-history":[{"count":5,"href":"https:\/\/www.filecloud.com\/blog\/wp-json\/wp\/v2\/pages\/3712\/revisions"}],"predecessor-version":[{"id":33560,"href":"https:\/\/www.filecloud.com\/blog\/wp-json\/wp\/v2\/pages\/3712\/revisions\/33560"}],"wp:attachment":[{"href":"https:\/\/www.filecloud.com\/blog\/wp-json\/wp\/v2\/media?parent=3712"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}