Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How we can load images even there is a concept call same origin policy?

I am building small offline web app using HTML and JavaScript. CSV file is used to store data.

To read CSV (using jquery-csv library) file I use following code.

<script>
    $(document).ready(function(){

        var filepath = 'data.csv';
        var data_string = $.get(filepath);
    });

</script>

But I can't read it because of following error.

XMLHttpRequest cannot load file:///C:/Users/Nimal/Desktop/javascript-csv/data.csv. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https


Then I could learned about same origin policy concept.

Then, I found many related articles from here.

  1. "Cross origin requests are only supported for HTTP." error when loading a local file
  2. XMLHttpRequest cannot load file. Cross origin requests are only supported for HTTP
  3. Ways to circumvent the same-origin policy

From Wikipedia,

In computing, the same-origin policy 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.

But I have a problem.

If I use <img src="abc.jpg"> I can load the image.

Why is there an exception for images?

How all we can load images, but we can't load other file types?

I thought same origin policy should apply all file types including images.

Or have I understand same-orgin-policy wrongly?

like image 813
I am the Most Stupid Person Avatar asked Sep 14 '17 05:09

I am the Most Stupid Person


People also ask

How do you solve the same-origin policy?

Same Origin Policy == JavaScript code can access/read data that come ONLY from the Same Origin. In other words Cross-Origin reads are not allowed. Here I have to make clear that Same Origin Policy doesn't block a Request from one origin to reach its destination, all it does is to hide the Response.

What does the same-origin policy allow?

The same-origin policy restricts which network messages one origin can send to another. For example, the same-origin policy allows inter-origin HTTP requests with GET and POST methods but denies inter-origin PUT and DELETE requests.

How do I get around the same origin problem with iframe?

A webpage inside an iframe/frame is not allowed to modify or access the DOM of its parent or top page and vice-versa if both pages don't belong to same origin. A frame or child page can bypass this restriction by setting window. document. domain variable to the same domain name as the parent's domain name.

What is the same-origin policy what about CORS How are they related?

The same-origin policy is an important security feature of any modern browser. Its purpose is to restrict cross-origin interactions between documents, scripts, or media files from one origin to a web page with a different origin. The HTTP protocol was extremely simple when it was first created.


1 Answers

To comprehend the problem, you have to understand the same origin policy (hereafter called as sop) and how it's being handled. It is an important concept when writing an application that allows users to browse the world wide web. Before that concept, many security violations has occurred.

In short, you can see sop as a tuple with three elements: (scheme,host,port).

  • scheme: the protocol. HTTP and HTTPS are different.
  • host: the url after the scheme. stackoverflow.com is different to google.com
  • port: https://stackoverflow.com is different to https://stackoverflow.com:9876/question (reason: default port is usually 80)

When you are visiting a page with a script that obtains information from multiple URLs. The tuple on this page is eg. tuple_main. If the script loads content from another URL, a tuple is generated from the URL: tuple_request. Two situations can occur here:

1) tuple_main == tuple_request
 ===> OK  => get content

2) tuple_main != tuple_request
 ===> NOK => do not get content and show that sop is being violated.

Initially, the sop is invented to protect content in your DOM against malicious adversaries. Throughout the years, this got broadened to secure other parts of the information that the browser is handling. A most notable example is the global javascript variables. 10+ years ago, developers started to store sensible information in their javascript as var foo in global space. It was easy for malicious adversaries to get it and abuse it...

Other extensions were added to secure Adobe Flash, MS Silverlight plugins, javascript mechanisms (like XMLHttpRequest), ect ... throughout the years. The sop ensures that the content of the webpage you are visiting does not leak to malicious adversaries (mostly by XSS)

Now, your question was initially (which is a description of the problem):

To read CSV (using jquery-csv library) file I use following code.

<script>
    $(document).ready(function(){

      var filepath = 'data.csv';
      var data_string = $.get(filepath);
    });
</script>

But I can't read it because of following error.

XMLHttpRequest cannot load file:///C:/Users/Nimal/Desktop/javascript-csv/data.csv. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https

Since the tuple is different, you are violating the sop. So you will get this message of course.

But your main question is

If I use <img src="abc.jpg"> I can load the image.

Why is there an exception for images?

To answer that, another concept and (eh ...) some history (old IE ages) are used here. To give developers means to use resources from a different sop location, a cross-origin concept is added. From this concept, there are three mechanisms (source):

  1. Cross-origin writes.

Here, we are talking about links to another sites, HTTP redirects and form submissions.

  1. Cross-origin reads

"Reading from another source" which is discouraged. But you can work-around it by embedding it. This leads us to the last mechanism:

  1. Cross-origin embedding

This is what you were doing when loading the csv file. This mechanism is added to allow web developers to use content from other sources such as stylesheets, scripts, images... You can see this as an "exception to the Same origin Policy principle".

If you are building a web page and you want to use jQuery (a script), then the browser will load that script. But embedded. You can run the script, but not read the content of the <script> tag.

That's what happens here at images. When loading the image by <img> tag, the browser is only reading the image. It cannot access the content (the byte information behind the file name that describes the whole image). Therefore, you can see the image on the page you're viewing.

If you want to load the image in a <canvas> element, then it will not be able to do so because it violates the rules. Your script is trying to access the byte information behind that file name. That is not allowed.

Why was I talking about IE history? Well, long time ago, IE was a mainstream browser. Since many companies started to "come online" they have build applications that uses IE for their business tasks. For example a financial employee was using IE to have a monthly summary of sales.

But the same origin policy was not extended in the way we have now. Loading sources from other domains were "not an issue". Companies started to setup websites with third party scripts (Ext js was used heavily back then), third party stylesheets and "third party" images. There are images on the world wide web that are free-to-use (and hosted by sites like tinypic, imageshack, ...). Lots of companies have used these images for their websites.

If those exceptions were not implemented, then lots of legacy websites would break. Images would not load. Scripts would not run. The economical cost of fixing it would be huge. So to anticipate that, this embedding mechanism got added.

A personal note: I am kinda happy that this exception exists otherwise maintaining a website would be a developer nightmare. If the sop is strict as intended, then you have to download the scripts and images and host it from your server. By this, your website can access these and use these. If a script got an update, you have to download it and overwrite your local script...

You are trying to read the content of the csv file which violates the security measurements behind the embedding mechanism.. Since it contains sensible information that should not be leaked to malicious adversaries, the browser informs you that you cannot load it. Just to prevent you for some security problems.

If you want to work locally, you have to use CORS. Or launch the browser without sop restrictions (albeit I don't recommend it).

like image 149
KarelG Avatar answered Oct 15 '22 09:10

KarelG