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

Manifest V3 declarativeNetRequest redirect sample is completely broken on latest chrome 121 #1082

Open
olokos opened this issue Feb 15, 2024 · 11 comments · May be fixed by #1083
Open

Manifest V3 declarativeNetRequest redirect sample is completely broken on latest chrome 121 #1082

olokos opened this issue Feb 15, 2024 · 11 comments · May be fixed by #1083

Comments

@olokos
Copy link

olokos commented Feb 15, 2024

⚠️ If you have general Chrome Extensions questions, consider posting to the Chromium Extensions Group or Stack Overflow.

Describe the bug
The declarativeNetRequest redirect does not do anything, sevice worker doesn't react and the browser behaves as if there's no extension at all, not redirecting anywhere.

To Reproduce
Steps to reproduce the behavior, or file the issue is found in:

  1. Get code from https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/api-samples/declarativeNetRequest/url-redirect
  2. Load as unpacked extension in Chrome 121 retail
  3. Go to one of the example websites listed such as: https://developer.chrome.com/docs/extensions/mv2/
  4. The website loads and nothing happens.

Expected behavior
Should redirect to:
https://developer.chrome.com/docs/extensions/mv3/intro/

Notes
I believe that Manifest V3 declarativeNetRequest API is currently completely broken and inactive.
Maybe it's a bug with Chrome itself?
Tested on chrome 121.0.6167.185

@patrickkettner patrickkettner linked a pull request Feb 15, 2024 that will close this issue
@patrickkettner
Copy link
Collaborator

Thanks for opening the issue!

DNR is not broken in Chrome 121, the site that the code is redirecting has gone through massive changes since the example was made. Specifically, it looks like the trailing slash on the matching domain is causing a problem. A change in the server's response handling can cause that.

@zhouhao
Copy link

zhouhao commented Feb 16, 2024

Thanks, olokos and patrickkettner.
I have the same issue, and I am using Chrome with Version 121.0.6167.184 (Official Build) (arm64).

I also find something interesting:

first I enabled Allow in Incognito, then, when I go to a fresh new Incognito window, I can notice it does redirect if I paste the mv2 link, but it will not redirect if I re-use the same Incognito window and paste the mv2 link again.
If I re-open a new Incognito window, the same thing happens as mentioned above.

@olokos
Copy link
Author

olokos commented Feb 16, 2024

Your "fix" does absolutely nothing, which I've tested before even writing this issue.

I've tested it now again and #1083 doesn't change anything at all.

Extensions are usually meant to affect websites that the extension developer has no control over, otherwise the server owner/developer would implement such functionality on the server's backend, making the extension completely useless and very inefficient.

If a simple redirect from one domain to another cannot be done with the browser extension and requires server specific backend changes, then this only confirms that this functionality is broken at its core - on a stable chrome build.

I'm not using beta or canary, on which that would be expected.

This makes it clear to me that currently either chrome or manifest v3 is non-functional and it seems like no fixing of the samples is going to change anything, as I was trying to achieve any sort of block or redirect last night and none of the functions related to block/redirect a website in the documentation have any effect, no errors, but no action taken.

Such a simple and core functionality, as redirect from a to b is completely and fundamentally broken, to the extent where even the official samples and documentation is non-functional.

This does not make Google Chrome manifest V3 feel like it's made by the Tech Giant that Google is, taking over 70% of web browsers market share, planning to force everybody to Manifest V3 in June of 2024, but instead this makes me feel like I'm commenting on some issue on some small browser startup project, made by college students in 15-minute breaks between classes, where the project started just a week ago and is still a buggy mess.

@olokos
Copy link
Author

olokos commented Feb 16, 2024

I've closed Chrome completely in task manager to start fresh after installing the sample extension, it does claim it started the service worker, but nothing happens.

image

I confirm that @zhouhao 's workaround of manually allowing the extension to run in incognito mode and then opening the mv2 website in incognito, does result in the redirect, but that's just a workaround, not a solution, the regular profiles mv3 redirect remains in a broken state as of today and the current version of "Stable" Chrome.

Making a change server side so the sample works, would only be a workaround of the problem, on the same level as running the extension in incognito to have it work in the first place. Which makes me believe that the issue indeed lies in the Manifest V3 or the Chrome browser itself.

Issues I listed above are still current and ongoing, please kindly let us know here, if there's any progress.

@oliverdunk
Copy link
Member

I had a brief look at this. It seems like as part of the move to new infrastructure @patrickkettner mentioned, we started using a service worker to handle requests. The rules in this sample are explicitly filtered to only work on main_frame requests (note the resourceTypes condition in rules_1.json) and hence do not apply.

In this specific case, it seems like removing the resourceTypes condition is enough. This is because the default value is "everything except main_frame", which happens to include the xmlhttprequest type we need.

That isn't a great solution generally though, since most sites don't have a service worker and would actually need the main_frame resource type.

@olokos We'll look at fixing this, but in the meantime, removing the resourceTypes condition should be enough to see things working. The issue here is caused by the specific site, and similar issues could've arisen with the webRequest approach in MV2. DNR is stable at this point and in use by many extensions, so any major issues would be surprising - hence the confusion in this issue because we would have had many other reports if it was an API level problem :)

@olokos
Copy link
Author

olokos commented Feb 21, 2024

Thanks for the explanation on what's going on here @oliverdunk

So if I understood correctly, the issue is that the redirect needs some arbitrary elements from the server response?

In the coming fix, could we have it work in the simplest - website content independent way?

So:
If request.domain==A
then request.domain=B

With no additional checks of whats on site A or downloading from it, so the redirect would not even access the A.com or send any dns queries, making it a true redirect from an extension.

With regards to HTTP/3 coming, the entire sea of web development frameworks and different ways to run the site, I think relying on specific page components, is bound to break at some point, as we can see already.

@oliverdunk
Copy link
Member

So if I understood correctly, the issue is that the redirect needs some arbitrary elements from the server response?

I may be misunderstanding what you're saying but I think it's slightly different.

Service workers allow a site to say "when a user tries to load my site, don't do what you'd normally do - just run this JS which returns a response".

So a valid service worker could look like this:

self.addEventListener('fetch', function(event) {
  return new Response(JSON.stringify({ hello: 'world' }), {
    headers: {'Content-Type': 'application/json'}
  });
});

In that case, should DNR rules apply when you try to load the site? DNR works at the network level and nothing ever happened on the network, so probably not - although in some cases this could be useful.

Without having looked at the code on https://developer.chrome.com/, I suspect it looks something like this:

self.addEventListener('fetch', function(event) {
  // Some other logic...
  return fetch(event.request);
});

In that case:

  • A request did happen, so DNR is relevant
  • It happened in JavaScript, so isn't really a main_frame request (hence why the current rule doesn't apply)

Hopefully that all makes sense? The hard balance here is that it would never be possible to block all "requests" made by all frameworks because they do a lot of trickery. In some cases, the new page may be generated entirely in JS and the network is never hit. So (even in Manifest V2) there are some limitations to what an extension can block generically without an understanding of how a specific site works.

@olokos
Copy link
Author

olokos commented Feb 21, 2024

Thanks, that does explain quite a lot in how it all works, appreciate it.

I have removed the resourceTypes section from the rules_1.json and the sample now does seem to work.

  1. But then currently, if I add a rule with a website that doesn't use a service worker, then the redirect won't work again, without adding main_frame to the rules_1.json in the extension?

  2. In that case, I imagine the incoming fix for this bug, would allow to redirect from both service_worker and websites that have main_frame?

  3. So the manual inspection of each website code that we redirect from, wouldn't be required, as it would work for both, without having to specify either one of them?

@oliverdunk
Copy link
Member

But then currently, if I add a rule with a website that doesn't use a service worker, then the redirect won't work again, without adding main_frame to the rules_1.json in the extension?

Right. The default value is ["xmlhttprequest", "sub_frame"... (everything except main_frame) - and service workers fall under xmlhttprequest. If you explicitly set main_frame, sites without service workers start working, but you are no longer covering service worker fetch requests. The solution to cover both cases would be including both xmlhttprequest and main_frame explicitly.

In that case, I imagine the incoming fix for this bug, would allow to redirect from both service_worker and websites that have main_frame?

Yeah, I think either that or we just update the sample to use a site without a service worker. We need to decide between covering a few more of the cases or keeping it simple.

So the manual inspection of each website code that we redirect from, wouldn't be required, as it would work for both, without having to specify either one of them?

It would work for both of these cases. There are still cases where a website could load without DNR applying, for example if the service worker is able to serve the page without making any network requests using local data it has stored. It should be rare, but is worth knowing.

@olokos
Copy link
Author

olokos commented Feb 21, 2024

Thanks, that does seem promising, looking forwards for an update with a fix, I hope it will be an update in chrome that will cover both of those scenarios, not just a sample update, as that woud require duplicate entries for each website, if the site content is not known.

I remember that MV2 did support http, https, websocket and secure websocket

So I guess we're not going to be able to redirect the websockets, even after the fix?

@oliverdunk
Copy link
Member

I hope it will be an update in chrome that will cover both of those scenarios, not just a sample update

I don't expect we will make any changes in Chrome based on this. You should be able to have a single entry with two resource types specified.

So I guess we're not going to be able to redirect the websockets, even after the fix?

There's also a "websocket" resource type you can use :)

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

Successfully merging a pull request may close this issue.

4 participants