Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blocking webRequest usecase - GM_xmlhttpRequest for Tampermonkey/Violentmonkey userscripts #176

Open
tophf opened this issue Mar 9, 2022 · 6 comments
Labels
topic: dnr Related to declarativeNetRequest

Comments

@tophf
Copy link

tophf commented Mar 9, 2022

GM_xmlhttpRequest/GM.xmlHttpRequest is a foundational feature for userscripts.

It needs the ability to set custom HTTP headers from the "forbidden" list e.g. cookie-related headers to implement proper isolation of cookies in incognito mode, otherwise userscripts running there would enable passive tracking of the main profile.

The declarativeNetRequest API cannot be used because its rules cannot be scoped to an individual request, only to the entire tab, which may have a lot of frames and a lot of different userscripts making overlapped requests. Currently, a blocking webRequest is used by Tampermonkey/Violentmonkey to set a dummy temporary header (removed in onBeforeSendHeaders) with a random id that's used to map the request's id in further events.

@dotproto
Copy link
Member

dotproto commented Mar 10, 2022

@tophf, I don't understand the association between request cookies and the user's main profile. To my knowledge Chrome's incognito implementation creates a temporary profile that's discarded when the incognito session ends. As such, there shouldn't be a need for user scripts to remove cookies from requests modification to remove main profile cookies from incognito requests. Am I missing something?

@dotproto dotproto reopened this Mar 10, 2022
@tophf
Copy link
Author

tophf commented Mar 10, 2022

Extensions in the default spanning mode for incognito use the same background script and the same cookie store as the main profile.

Either way, the tracking problem is just one example. Userscripts also need to set/get a cookie explicitly just for a request, without affecting the main profile. Userscripts also often need to set Referer, for which there's no other way than to use a blocking webRequest. Maybe other headers from that list too.

Without a blocking webRequest we need another way to track the lifecycle of the request made via fetch in the background script or XMLHttpRequest in a tab via observational webRequest.

As I explained declarativeNetRequest can't be used now because we would have to allow just one request at a time in the entire browser to be able to track it reliably via the observational webRequest. Maybe it can be extended in the future e.g. by adding a condition for the request like headerFilter so we set a dummy value there in fetch, add a dynamic rule in DNR to set the necessary headers for just this one request. Still, it won't help with receiving the set-cookie header, reading it, and stripping it to prevent it affecting the main profile.

Anyway, currently this is purely academic because ManifestV3 still doesn't have a solution for userscript extensions.

@dotproto
Copy link
Member

Thanks for calling out spanning mode; that slipped my mind.

My first impression is that it may be best for browsers to consider directly supporting more of GM.xmlHttpRequest's capabilities rather than requiring extension authors to. Perhaps when we add user script support to the scripting API we could/should also support GM APIs. Maybe even without that prefix or with different one?

@tophf
Copy link
Author

tophf commented Mar 14, 2022

Native support would be a nice feature, especially if the browser can show a native confirmation dialog for the URL per the satellite @connect declaration in the userscript's header, which currently is only implemented in Tampermonkey. These keys list the sites that the userscript can connect to: the explicitly listed sites will be silently allowed because they're granted at the install time, whereas * will display a dialog whenever an unknown site is accessed with a few buttons: allow, deny, [x] remember.

@derjanb
Copy link

derjanb commented Mar 15, 2022

My first impression is that it may be best for browsers to consider directly supporting more of GM.xmlHttpRequest's capabilities rather than requiring extension authors to.

As a starting point allowing fetch to set all headers even the "forbidden" ones would be great.

Another thing would be raw access to the received headers or even better a way to modify them before they are processed by the browser.
So basically blocking webRequest functionality but only for this request. Maybe this can be implemented with a RequestController similar to the AbortController [edit] or by enabling FetchEvent for the extension's own requests?[/edit]

we could/should also support GM APIs.

I think there a lot more extensions that modify their own request via webRequest to fit their needs. So I'd favor a more general solution, except this is what you mean with "support GM APIs".

@CodFrm
Copy link

CodFrm commented Nov 21, 2023

The deadline for manifest v3 has been determined. Is there still no solution to this problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: dnr Related to declarativeNetRequest
Projects
None yet
Development

No branches or pull requests

5 participants