I want my app with a REST API to be accessible in different flavors:
I want to limit the list of sites for my app to be accessible from by a whitelist.
I know how to do it with CORS but I'm not sure if it works with GM_xmlhttpRequest
the same way since GM_xmlhttpRequest
does not require the Origin
header to be sent back from a server.
I don't care for a client but I still need to check on a server from which site the request was sent and answer with something like {response:"site not supported"}
if it isn't in a whitelist.
So, when I run a userscript on some webpage and make a GM_xmlhttpRequest
, can the server detect the origin?
You cannot use the Origin
header to reliably restrict access by userscripts to your API.
By default, GM_xmlhttpRequest()
Doc does not send the Origin
header at all. Nor does GM_xmlhttpRequest
block cross-site requests; that is the main reason that GM_xmlhttpRequest
exists.
Also, for Greasemonkey (Firefox) and Tampermonkey (Chrome), GM_xmlhttpRequest
does not send the referer
header, by default.
However, both headers can be overridden to be whatever the script-writer wants.
Here is a demo script that spoofs both headers (use a packet sniffer to see for yourself):
// ==UserScript==
// @name _Test Fake Referrer
// @include http://stackoverflow.com/questions/18178934/*
// @grant GM_xmlhttpRequest
// ==/UserScript==
GM_xmlhttpRequest ( {
method: "GET",
url: "http://www.google.com",
headers: {
referer: "http://microsoft.com",
origin: "http://microsoft.com"
}
} );
A plain Chrome userscript is not so kind to the script developer. Native Chrome userscripts never send the Origin
header and always send the current page as the referer
.
If you try to spoof either of these headers, the console will show errors like:
Refused to set unsafe header "referer"
Refused to set unsafe header "origin"
This is one more reason to use Tampermonkey for your Chrome userscripts.