Opened 9 months ago

Last modified 5 months ago

#6730 new defect

Subscribe links don't work with redirects

Reported by: greiner Assignee:
Priority: Unknown Milestone:
Module: Platform Keywords:
Cc: kzar, sebastian, pfrey, arthur Blocked By:
Blocking: Platform: Unknown / Cross platform
Ready: no Confidential: no
Tester: Unknown Verified working: no
Review URL(s):

Description

Environment

Ubuntu 16.04
Chrome 66
Adblock Plus 3.1

How to reproduce

  1. Go to https://twitter.com/greiner12/status/1003985379865833472
  2. Click on link in tweet

Observed behaviour

Tab opens with browser error page.

Expected behaviour

Tab opens with Adblock Plus options page asking you to confirm adding the EasyList filter list.

Further information

We've introduced subscribe.adblockplus.org URLs so that subscribe links can be shared on third-party platforms where URLs are automatically converted into links. However, major social networks such as Facebook, Twitter and YouTube not only convert URLs to links but also replace them with links to their own website which then redirect to the URL you wanted to link to.

However, since Adblock Plus merely checks URLs in links that are embedded on a page and not URLs it encounters in a redirect chain originating from a user clicking a link, it doesn't recognize these subscribe links.

Note that to avoid misuse, this feature should preferrably still be limited to actions that are initiated by the user so that it cannot be triggered programmatically by a website.

Change History (11)

comment:1 Changed 5 months ago by kzar

I can reproduce this as you described, but I can't see an obvious way to fix the behaviour on the extension side.

My only suggestion is that we set up a webserver to respond to those requests with a nicely formatted "Would you like to add this subscription?" page that shows the user more information about the subscription in question. I suppose we'd have to be quite careful about which subscriptions could be linked to in this way, perhaps with a whitelist.

comment:2 Changed 5 months ago by sebastian

Instead of handling HTTP(S) subscription links in a content script, we could detect those through the webRequest (or webNavigation) API, and then close the tab, and switch to the options page with the dialog to add the subscription. This would not only work for redirects, but also for subscription links that aren't in the DOM at page load yet (which is another scenario that is currently not supported).

comment:3 Changed 5 months ago by kzar

Well, I attempted to do it that way but I didn't have much luck. The onCommitted navigation event fired for the original URL, not the URL we redirected to. I saw the onHeadersReceived event firing but for some reason it reported a 200 response with the original URL... despite when I used curl -I I saw the proper redirection response. Even if we figured out how to reliably capture navigations to subscription links, we'd then have trouble like Thomas hints figuring out if the user intended to trigger that navigation.

comment:4 Changed 5 months ago by sebastian

I don't think you have to bother about status codes or headers. onBeforeRequest is called for each request (in the redirect chain), so you just need to match the URL and if it's in the form of a subscribe link, close the tab and prompt the user to add the subscription through the options page.

However, it's true that with this approach we cannot check if the URL was requested as a result of a user's gesture, or programmatically. But I guess, we have to live with that.

comment:5 follow-up: Changed 5 months ago by kzar

Oh yea, you're right, the onBeforeRequest does what we want here.

So, we could catch main_frame requests to https://subscribe.adblockplus.org/* with onBeforeRequest, and then open the options page instead. But, I don't think we have a way to know if the request was user triggered.

Allowing websites to trigger the options page to open a Adblock Plus subscription dialog might be a worse user experience than having these redirected subscription link clicks fail. What do you think Thomas?

comment:6 in reply to: ↑ 5 Changed 5 months ago by greiner

Replying to sebastian:

However, it's true that with this approach we cannot check if the URL was requested as a result of a user's gesture, or programmatically. But I guess, we have to live with that.

Unfortunately, I don't think we can live with that. Imagine any of the dozens of tabs that users might have open, programmatically triggering the options page to show up and suggesting to add a filter list.

Not only could that be annoying and confusing to the user but it would look like Adblock Plus is the one who's suggesting to add a filter list. That last point can have quite severe implications.

Replying to kzar:

Allowing websites to trigger the options page to open a Adblock Plus subscription dialog might be a worse user experience than having these redirected subscription link clicks fail. What do you think Thomas?

I wouldn't worry about the failing clicks at this point. All we'd have to do to fix that is set up a static web page under subscribe.adblockplus.org, the foundation for which has already been laid way back in #2248.

But yes, a bad user experience is one of the various issues with that approach, as mentioned above.

comment:7 Changed 5 months ago by sebastian

If a website is programmatically trying to open a new document (without user gesture), this is already blocked by default (through the popup blocking mechanism in all modern browsers).

(And even if there would still be a way for a website to programmatically open the options page, they can anyway by navigating to chrome-extension://cfhdojbkjhnklbpkdaibdccddilifddb/options.html. Sure the user wouldn't be prompted to add a subscription then, but that is just a coincidence since back then we decided merely due to technical issues to pass this information through messaging rather than through an URL fragment. But the annoyance would be similar, and it still look like it's us doing it.)

Last edited 5 months ago by sebastian (previous) (diff)

comment:8 Changed 5 months ago by kzar

...they can anyway by navigating to chrome-extension://cfhdojbkjhnklbpkdaibdccddilifddb/options.html

I'm not sure that's true. I just did a test and ran window.location.href = "chrome-extension://cfhdojbkjhnklbpkdaibdccddilifddb/options.html" (well with the right extension ID for my unpacked copy of the extension) in the console for a random tab and it navigated me to about:blank instead. Perhaps there's another way for a website to get around that though?

comment:9 follow-up: Changed 5 months ago by sebastian

You seem to be right, I just tried it out and both setting window.location.href to an extension page, or clicking a link with an extension page URL in it's href attribute, navigates to about:blank.

Perhaps, we could use a combination of content script (in order to detect if the link was clicked through user gesture) and onBeforeRequest listener (in order to account for the final URL).

comment:10 in reply to: ↑ 9 Changed 5 months ago by kzar

Replying to sebastian:

Perhaps, we could use a combination of content script (in order to detect if the link was clicked through user gesture) and onBeforeRequest listener (in order to account for the final URL).

Yea, I considered that too. The content script could send a message when any link was clicked, then we store some record of "user initiated" navigation in the background. Then (hopefully afterwards) when we intercept the request to the subscription URL, if the initiator URL matches the URL we stored already we could trust it.

Even ignoring the added complexity, I'm not sure that's feasible in practice. I wonder if we can guarantee the message from the content script would arrive before we intercept the request. Also, in the case of a request that was redirected twice we might no longer recognise the URL. We'd have to somehow know to trash these URL too, otherwise we would create a memory leak.

comment:11 Changed 5 months ago by sebastian

I suppose, we could listen to onBeforeRedirect and then follow the whole redirect chain form the original URL of the link that has been clicked by the user.

Or maybe a simpler but sufficient approach would be to just record that any link has been clicked by the user in a particular tab, and if navigation to a subscribe link occurs within that tab, while the tab is still active, prompt the user to add the subscription.

Note: See TracTickets for help on using tickets.