I want my app with a REST API to be accessible in different flavors:
- From the same domain (use normal AJAX request here)
- From another domain via script attached by site owner (CORS)
- From another domain via userscript (GM_xmlhttpRequest (?))
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 theOrigin
header at all. Nor doesGM_xmlhttpRequest
block cross-site requests; that is the main reason thatGM_xmlhttpRequest
exists.Also, for Greasemonkey (Firefox) and Tampermonkey (Chrome),
GM_xmlhttpRequest
does not send thereferer
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):
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 thereferer
.If you try to spoof either of these headers, the console will show errors like:
This is one more reason to use Tampermonkey for your Chrome userscripts.