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

Add $cookie modifier support #961

Closed
ameshkov opened this issue Feb 21, 2018 · 3 comments
Closed

Add $cookie modifier support #961

ameshkov opened this issue Feb 21, 2018 · 3 comments
Assignees
Milestone

Comments

@ameshkov
Copy link
Member

ameshkov commented Feb 21, 2018

Why:

  • To suppress common tracking cookies when we're not able to block the URL
  • Cookies are often used by anti-adblocking tools and having such modifier will help a lot

I'd like this modifier to be able to:

  • Completely block all cookies set by a request matching a rule
  • Or block a single cookie (or multiple cookies)

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.

  • ||example.org^$cookie=NAME;maxAge=3600;sameSite=lax -- every time AdGuard encounters a cookie called NAME in a request to example.org, it will do the following:
    • Set its expiration date to current time plus 3600 seconds
    • Makes the cookie use Same-Site "lax" strategy.
  • ||example.org^$cookie -- blocks ALL cookies set by example.org. This is an equivalent to setting maxAge to zero.
  • ||example.org^$cookie=NAME -- blocks a single cookie named NAME
  • ||example.org^$cookie=/regular_expression/ -- blocks every cookie that matches a given regular expression

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:

  • @@||example.org^$cookie -- unblocks all cookies set by example.org
  • @@||example.org^$cookie=NAME -- unblocks a single cookie named NAME
  • @@||example.org^$cookie=/regular_expression/ -- unblocks every cookie matching a given regular expression

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

  • $cookie=__cfduid -- blocks CloudFlare cookie everywhere
  • $cookie=/__utm[a-z]/ -- blocks Google Analytics cookies everywhere
  • ||facebook.com^$third-party,cookie=c_user -- prevents Facebook from tracking you even if you are logged in
@ameshkov ameshkov self-assigned this Feb 21, 2018
@ameshkov ameshkov changed the title Add a $cookie modifier Proposition: add a $cookie modifier Feb 22, 2018
@ameshkov ameshkov changed the title Proposition: add a $cookie modifier Proposition: add $cookie modifier support Mar 4, 2018
@ameshkov ameshkov added this to the 3.0 milestone Sep 17, 2018
@ameshkov ameshkov assigned Mizzick and unassigned ameshkov Oct 2, 2018
@ameshkov ameshkov changed the title Proposition: add $cookie modifier support Add $cookie modifier support Oct 24, 2018
@ameshkov
Copy link
Member Author

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

@ameshkov
Copy link
Member Author

@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
Copy link
Contributor

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

ameshkov pushed a commit that referenced this issue Dec 28, 2018
ameshkov pushed a commit that referenced this issue Dec 28, 2018
@zzebrum zzebrum closed this as completed Jan 9, 2019
adguard pushed a commit that referenced this issue Jul 8, 2021
Merge in EXTENSIONS/browser-extension from feature/AG-8778 to feature/AG-2737

* commit '87f08fe6234fc33357089942134fb3ab586119bb':
  feature:AG-8778 validate settings json
  feature:AG-8778 validate settings json
  feature:AG-8778 validate settings json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants