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

Websites cannot know if cookies are disabled #15

Closed
baptx opened this issue Mar 20, 2020 · 10 comments
Closed

Websites cannot know if cookies are disabled #15

baptx opened this issue Mar 20, 2020 · 10 comments
Assignees

Comments

@baptx
Copy link

baptx commented Mar 20, 2020

While blocking cookies with this addon, the navigator.cookieEnabled property will still return true so a website will think cookies are enabled.
Switching language on a search engine like DuckDuckGo should work with cookies disabled since they have a fallback solution but it fails because the website tries to use cookies if they are enabled.
Example: https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_nav_cookieenabled

To avoid this problem, we have to disable a website's cookies through the web browser settings directly but it is less convenient than using a browser addon since it needs more clicks.

I heard it is not possible to solve this problem through an addon unless contentSettings web extension API is supported by Firefox but maybe there is a workaround like you did to block read / write access to cookies through JavaScript? Overriding the JavaScript variable for example.

@craigmiskell
Copy link
Owner

It doesn't look like something that can be managed in firefox; as you say the contentSettings API would be handy (really handy; I could probably replace 90% of the code detecting/managing code with that), but Firefox doesn't have it.

Surprisingly it does look possible to override navigator.cookieEnabled (in theory/general). I need to think through if there are any reasonable negative side-effects from this (e.g. third party cookies, if enabled), or other gotchas. It would need to be done with a content script, in the context of the page, so is subject to being prevented by CSP (already a bit of a pain). It looks like the CSP for duckduckgo would prevent this approach, although I should test that to be sure.

@craigmiskell craigmiskell self-assigned this Mar 21, 2020
@baptx
Copy link
Author

baptx commented Mar 21, 2020

I think CSP rules should not be a problem if we override them and maybe restore them when the addon work is done. Some addons like Header Editor (https://github.com/FirefoxBar/HeaderEditor) can change CSP rules by modifying the HTTP response header. Another solution could be using a Greasemonkey script to override navigator.cookieEnabled but I am not sure if CSP rules would be a problem.

@craigmiskell
Copy link
Owner

craigmiskell commented Mar 21, 2020

I do not feel at all comfortable with modifying CSP headers; they'd have to be modified for every request and I don't see how the change could be undone after we've done our work (they're headers that are interpreted when the resource is fetched by the browser, not state that can be modified at will later). We'd have to add an 'unsafe-inline' (or maybe 'unsafe-eval'?) because of the way we have to eval code; adding a "script" tag means we could add a sha256 script-src to the header, but wouldn't run early enough to be reliable. And adding 'unsafe-inline' or 'unsafe-eval' to pages which have carefully and well-defined CSP that does not already have that would substantially lower their security posture, something I am not willing to do.

@craigmiskell
Copy link
Owner

@baptx I spent a bit more time with CSP and adding a sha256 script-src, and it seems to work well enough; it still has race conditions (adding a script tag may happen after other on-page javascript has already executed and tried to set cookies), but it's better than having an eval be blocked entirely by CSP and having to fall back to event-handlers noticing cookies being set. So I'm going to run with that.

However: I then added an override for navigator.cookieEnabled to reflect the cookiemaster configuration for the current page, and it worked in a simple synthetic test. On visiting duckduckgo.com and trying to change the language, with cookies disabled, but it still doesn't work (the page immediately reloads, presumably to pick up the new language settings, and never seems to query navigator.cookieEnabled). I did a very quick search through their javascript but couldn't find any reference to navigator.cookieEnabled. I'd really like to find some real-life example using it so that I can test with/without the new code and confirm it actually helps. What made you think duckduckgo.com uses this property? Can you point me at where they do, so I can see it happening?

@baptx
Copy link
Author

baptx commented Apr 14, 2020

In fact it looks like DuckDuckGo is not using navigator.cookieEnabled (maybe they have been using it in the past). However they are using another method to detect if cookies are enabled, probably by trying to create a cookie through JavaScript and trying to read it (I saw this error message when blocking cookies in Firefox: Request to access cookies or storage on “<URL>” was blocked because of custom cookie permission.).
If cookies are enabled and you change the language, DuckDuckGo creates a cookie like l=fr-fr for French language. If cookies are not enabled, they use an HTTP GET parameter kl=fr-fr.
The best thing would be an addon option to spoof the navigator.cookieEnabled value, so users can have more control:

  • set navigator.cookieEnabled to false to use fallback features working without cookies if the website is checking the value
  • leave navigator.cookieEnabled to true to bypass restrictions if the website if checking the value and displaying an error message asking to enable cookies

Currently I am using uMatrix addon which allows cookie creation locally but does not send them to the server. This can be a useful feature to bypass restrictions if a website tries to block access to users without cookies enabled, by trying to create a cookie with JavaScript.

@baptx
Copy link
Author

baptx commented Apr 14, 2020

@craigmiskell I think the reload bug you have experienced comes from the fact that your addon blocks writing cookies but does not block reading cookies. I reproduced the bug by allowing cookies on DuckDuckGo, enabling / disabling language change (which left a "previous language" cookie ah=fr-fr). When I blocked cookies with your addon, I was not able to change language until I removed the cookie "ah".
There is also a bug if cookies are enabled with your addon on DuckDuckGo: once we enable the language change, we cannot disable it.

craigmiskell added a commit that referenced this issue Apr 18, 2020
Requested in #15; may or may not help, probably won't make life significantly worse
@craigmiskell
Copy link
Owner

Version 1.1.4 has been released; it overrides navigator.cookieEnabled to return the appropriate value for the current user-chosen config for the current page (true => allowed, false => blocked). Hopefully it doesn't break any other sites, but only time will tell.

@baptx
Copy link
Author

baptx commented Apr 18, 2020

@craigmiskell would it be possible to block cookies without overriding navigator.cookieEnabled by checking an option in the addon settings? This would avoid possible censorship popups that I mentioned previously.
I also tested the new version but the bug described in my previous comment is still here.

@craigmiskell
Copy link
Owner

craigmiskell commented Apr 18, 2020

would it be possible to block cookies without overriding navigator.cookieEnabled by checking an option in the addon settings? This would avoid possible censorship popups that I mentioned previously.

Many things are possible :) I'm not sure; it's a fairly low level detail to expose to an average user. Would you be expecting it to be a single setting for all sites? Per-site would make for a challenging user interface design, but a global setting might not even do what you need it to do.

I also tested the new version but the bug described in my previous comment is still here.

I've opened a new issue to keep the discussion clearer: #18

@baptx
Copy link
Author

baptx commented Apr 19, 2020

@craigmiskell a single setting should be fine (we could easily enable / disable it when needed for the current tab). The addon uMatrix has a similar single setting for JavaScript called Spoof <noscript> tags. If enabled, <noscript> tags are working, like if JavaScript is really disabled in the web browser.

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

No branches or pull requests

2 participants