Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Origin header is present in non-GET requests in Chrome App even if the server domain URL is added to the permissions

I'm working on a chrome application that will be communicating with the server through RESTful API.

Without adding the server URL to the permissions in the manifest.json I can see that Chrome sends all requests with the origin header (chrome-extension://cpndc....) and if any of these requests has non - standard headers it also sends a preflight OPTIONS request - this is all as expected.

After adding the domain to the permissions, preflight OPTIONS is not sent anymore. The origin header is not present in the GET calls but it is still present in POST, PATCH, MERGE calls.

This causes problems as the CORS implementation on the server I will use assumes that requests with origin header are CORS requests and responds with 403 error as it doesn't like the origin - this origin with chrome-extension is not on the list of accepted origins.

As per the CORS specification, the expectation is that the origin header should be only added in cross domain request https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#Origin but since the server domain is added to the permissions, I would expect that not only GET but also other requests don't have it.

The question is: is this a bug in Chrome Apps CORS implementation?

Summary of my findings when working with Chrome Apps:

If endpoint URL is not added to the permissions in the manifest file (CORS will kick in): - Chrome App sends the origin header in all type of requests - Chrome App sends the OPTIONS preflight for all requests that have non-standard headers

If endpoint URL is added to the permissions in the manifest file (security for requests to that domain is off) - Chrome Apps doesn't send the OPTIONS preflight anymore (as expected) - Chrome App sends the origin header in non-GET requests only (should not send origin at all)

Example permissions file:

  "permissions": [
"http://api.randomuser.me/*"

]

Example app code:

window.onload = function() {

function get(){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://api.randomuser.me/?seed=bigFish", true);
    xhr.setRequestHeader('Authn', 'abcdefghijklmnopqrstuvxyz');
    xhr.onload = function (e) {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          console.log(xhr.responseText);
        } else {
          console.error(xhr.statusText);
        }
        post();
      }
    };
    xhr.onerror = function (e) {
      console.error(xhr.statusText);
    };
    xhr.send(null);   
}

function post() {
    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://api.randomuser.me/', true);
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader('Authn', 'abcdefghijklmnopqrstuvxyz');
    xhr.onload = function () {
        // do something to response
        console.log(this.responseText);
    };
    xhr.send('user=person&pwd=password&organization=place&requiredkey=key');
}

document.getElementById('mybutton').addEventListener('click', function() {
    get();
});

};

GET request without the origin header: GET request without the origin header

POST request with the origin header: POST request with the origin header

like image 500
woj.sierak Avatar asked Mar 05 '14 13:03

woj.sierak


People also ask

How do I enable Access-Control allow origin on chrome?

If you want to activate the add-on, please open the toolbar popup and press the toggle button on the left side. The icon will turn to an orange C letter.

How do you fix CORS missing Allow origin?

If the server is under your control, add the origin of the requesting site to the set of domains permitted access by adding it to the Access-Control-Allow-Origin header's value. You can also configure a site to allow any site to access it by using the * wildcard. You should only use this for public APIs.

How do I set the Access-Control allow Origin header?

Limiting the possible Access-Control-Allow-Origin values to a set of allowed origins requires code on the server side to check the value of the Origin request header, compare that to a list of allowed origins, and then if the Origin value is in the list, set the Access-Control-Allow-Origin value to the same value as ...


1 Answers

I just found a similar question on StackOverflow:

Chrome adding Origin header to same-origin request

and one of the answers pointed to the spec: rfc6454#section-7.3:

https://www.rfc-editor.org/rfc/rfc6454#section-7.3

According to it the user agent MAY include an Origin header field in any HTTP request.

This means that the origin header doesn't have to relate to CORS.

like image 66
woj.sierak Avatar answered Sep 28 '22 09:09

woj.sierak