AdguardTeam / AdguardBrowserExtension

AdGuard browser extension
https://adguard.com/
GNU General Public License v3.0
3.02k stars 321 forks source link

Add $cookie modifier support #961

Closed ameshkov closed 5 years ago

ameshkov commented 6 years ago

Why:

I'd like this modifier to be able to:

Specification

The $cookie modifier completely changes rule behavior. Instead of blocking a request, this modifier makes us suppress or modify the Cookie and Set-Cookie headers.

Multiple rules matching a single request In case if multiple $cookie rules match a single request, we will apply each of them one by one.

$cookie syntax

The rule syntax depends on whether we are going to block all cookies or to remove a single cookie. The rule behavior can be changed with maxAge and sameSite modifiers.

Important: in the case of a regular expression matching, two characters must be escaped: comma (,) and ($). Use (\) for it. For example, escaped comma looks like this: \,.

$cookie rules are not affected by regular exception rules (@@) unless it's a $document exception. In order to disable a $cookie rule, the exception rule should also have a $cookie modifier. Here's how it works:

Limitations $cookie rules support a limited list of modifiers: domain, ~domain, important, third-party, ~third-party.

Implementation details

I suppose it is enough to intercept Cookie/Set-Cookie headers and there's no need to mess with the document.cookie property.

Let's look at an example.

  1. ||example.org^$cookie=i_track_u should block the i_track_u cookie coming from example.org
  2. We've intercepted a request sent to https://example.org/count
  3. Cookie header value is i_track_u=1; JSESSIONID=321321
  4. First of all, modify the Cookie header so that the server doesn't receive the i_track_u value. Modified value: JSESSIONID=321321
  5. Wait for the response and check all the Set-Cookie headers received from the server.
  6. Remove the one that sets the i_track_u cookie (or modify it and strip that cookie if it contains more than one)
  7. Now we need to make sure that browser deletes that cookie. In order to do it, we should add a new Set-Cookie header that sets i_track_u with a negative expiration date: Set-Cookie: i_track_u=1; expires=[CURRENT_DATETIME]; path=/; domain=.example.org.

Step 7 must not be executed when the rule has the third-party modifier. third-party means that there is a case (first-party) when cookies must not be removed, i.e. they can be actually useful, and removing them can be counterproductive. For instance, Google and Facebook rely on their SSO cookies and forcing a browser to remove them will also automatically log you out.

Real-life examples

ameshkov commented 5 years ago

These two issues might change the way we're going to implement this:

ameshkov commented 5 years ago

@atropnikov see the last comment here: https://bugs.chromium.org/p/chromium/issues/detail?id=827582#c48

I have a change being reviewed right now (http://crrev.com/c/1338165) which will allow extensions to modify/view the headers if the 'extraHeaders' value is used in the extraInfoSpec of the listener. Once this is in Canary, you should be able to use this to match the previous behavior.

maximtop commented 5 years ago

In order to test

turn off all filters

// test cookie removal by the domain name and cookie name go to yandex.ru see that there is a cookie with the name yandexuid and it’s expiration will happen in 10 years add rule ||yandex.ru^$cookie=yandexuid;maxAge=3600;sameSite=lax reload yandex.ru now expiration date is set to the current time plus one hour and the sameSite property has value lax

// test all cookie removal by a domain name go to google.com add rule ||google.com^$cookie reload page all cookies set by google.com should be removed

// test cookie removal by regexp add rule $cookie=/_ga/ go to meduza.io find out that cookies containing _ga were removed add rule @@||meduza.io$cookie=/_ga/ reload meduza.io again and check that cookies containing _ga appeared again

all cookies removals or their modifying should be visible in the filtering log

also, check that in the integration mode cookies are not modified at all