Javascript, Chrome extension: overriding cookie getter and setter

空扰寡人 提交于 2019-12-11 11:54:53

问题


EDIT: After being recommended to work with headers, I asked a similar question here.

I'm trying to develop a Chrome extension that analyzes cookies being set/retrieved by websites and, if a cookie doesn't meet certain requirements, stops it from being set/retrieved.

I figured I would have to override the cookie setter and getter.

I have found similar questions:

Cookie Law, Cookie setter & getter

Safely overriding document.cookie in Google Chrome extension

Defining a getter for document.cookie

Retrieving document.cookie getter and setter

Reading the answers I have to say I am quite confused and am no longer sure what I'm trying to do is even possible.

Nevertheless, referring to question #3 in particular, I tried coming up with a simple test extension that overrides cookie getter and setter with functions that don't do anything (so no cookie should ever be set while this extension is active). These are the 3 files the extension is made of.

manifest.json

{
  "manifest_version": 2,

  "name": "Test",
  "description": "Test extension",
  "version": "1.0",

  "permissions": [
    "<all_urls>",
    "tabs",
    "webRequest",
    "webRequestBlocking"
  ],

  "background": {
    "scripts": ["background.js"]
  }
}

background.js

chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    chrome.tabs.executeScript(null, {
      file: "cookiescript.js"
    });
  }, {
    urls: [
      "<all_urls>"
    ]
  }, ["blocking"]);

cookiescript.js

var old_cookie = document.cookie;

Object.defineProperty(document, 'cookie', {
  get: function() {
    console.log('Getting cookie...');
    return '';
  },
  set: function(val) {
    console.log('Setting cookie...');
  }
});

document.cookie = old_cookie;

I usually test this on en.wikipedia.org as it sets various cookies the moment you visit it. However, with the above extension, the console log becomes filled with Getting cookie... alternated with Uncaught TypeError: Cannot redefine property: cookie, and when I check cookies stored, I can see that Wikipedia created all the cookies it wanted regardless of my extension.

The error seems to speak clear: you can't override cookie setter and getter, but the fact that other questions (#3 in particular) were answered saying to do just that, I am not sure.

Alternatively, I tried using this version of cookiescript.js, which adopts the (deprecated) defineSetter and defineGetter

var old_cookie = document.cookie;

document.__defineSetter__('cookie', function() {
  console.log('Setting cookie...');
});
document.__defineGetter__('cookie', function() {
  console.log('Getting cookie...');
  return ('');
});

document.cookie = old_cookie;

Console log results in an alternation of Setting cookie... and Getting cookie..., but again, looking at cookies saved, it looks like Wikipedia successfully set all of its cookies.

Would anyone be able to point out what I'd have to do to successfully be in-between cookie setting/getting so that I could stop it, or explain if what I'm trying to do is just impossible?

My wild guess would be that the overriding of getter/setter actually happens, but only after the website set/got its cookies, but I'd have no idea how to make sure my overriding happens first instead (I figured the use of blocking onBeforeRequest would've achieved that, but I seem to be wrong), or if it's simply impossible to do so.

EDIT: I previously mentioned how a different extension to list cookies would not be able to retrieve them, so I thought I successfully overrode the getter. I was mistaken, this extension was broken, and when fixed it was displaying all the cookies.


回答1:


I think you're trying hard to reinvent the wheel here. Quoting the docs:

Use the chrome.cookies API to query and modify cookies, and to be notified when they change.

I get it that sometimes you want to prevent it in the first place, and let's take a look at that as well, but you've got to understand how cookies work. There are 2 kinds of cookie set operations:

  1. By the client, by document.cookie manipulation. Then your approach may help, but to ensure that the cookie is intercepted you cannot rely on programmatic injection, it is indeed too slow. You need to declare it in the manifest with a proper run_at parameter:

    "content_scripts" : [{
      "matches" : ["<all_urls>"],
      "js": ["cookiescript.js"],
      "run_at": "document_start"
    }]
    

    This will ensure your code executes before anything else on the page (before there is even anything in the DOM).

  2. By the server as part of the HTTP response. It may even be HTTP-Only cookie that's not exposed to document.cookie.

    You can intercept that as well, but you need to use webRequest for that, specifically a blocking response to onHeadersReceived can examine and modify headers that set cookies, and a blocking response to onBeforeSendHeaders can modify cookies reported to the server.



来源:https://stackoverflow.com/questions/35349837/javascript-chrome-extension-overriding-cookie-getter-and-setter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!