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:
POST request with the origin header:
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.
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.
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 ...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With