Javascript to selectively block cookie creation with other javascript on the page

I wrote this javascript which blocks all other javascript from creating cookies on the page (I have jquery on the page too):

jQuery(document).ready(function () {
  Object.defineProperty(document, 'cookie', {
    get: function () {
        return '';
    },
    set: function (value) {
    }
  });
});

      

Now I have to move on. I need to selectively block cookies, something like this:

jQuery(document).ready(function () {
  Object.defineProperty(document, 'cookie', {
    get: function () {
        if (value == ...) {
          //call to "parent" function here  
        } else {
          return '';
        }
    },
    set: function (value) {
        if (value == ...) {
          //call to "parent" function here
          //document.cookie ???
        }         
    }
  });
});

      

Is it possible to call the parent / native function? I tried with document.cookie, but the browser started a loop by calling my function again (that's correct).

Thank you in advance

Mariella

+3


source to share


1 answer


You cannot do this while your getter / setter proxy is active.

The problem is that it document.cookie

doesn't use JavaScript getters and setters, but (presumably) native ones that we can't access.
You can see this by calling Object.getOwnPropertyDescriptor

:

JSON.stringify(Object.getOwnPropertyDescriptor(document, 'cookie'));

      

(I cannot make this fragment because fragments cannot access cookies).
In Chrome:

{
    "value": "...",
    "writable": true,
    "enumerable": true,
    "configurable": true
}

      

In Firefox:

undefined

      



And without holding the function that handles the assignment, you have no means of calling it.

However, if you delete document.cookie

, Jon Skeet puts it down , it will automatically return to normal.

So what you can do is save the assignments somewhere, remove your proxy at some point ( window.onunload

eventually) and reassign everything to document.cookie

there, like

function getCookies()
{
    var cookies = {};
    var list = document.cookie.split(';');
    for(var i = 0; i < list.length; i++)
    {
        var split = list[i].split('=');
        cookies[split[0].trim()] = split[1];
    }
    return cookies;
}

function hijackCookies()
{
    var cookies = getCookies();
    Object.defineProperty(document, 'cookie',
    {
        configurable: true,
        enumerable: true,
        get: function()
        {
            var list = [];
            for(var key in cookies)
            {
                list.push(key + '=' + cookies[key]);
            }
            return list.join('; ');
        },
        set: function(value)
        {
            var split = value.split('=');
            var key = split[0].trim();
            if(/* YOUR FILTER HERE */)
            {
                return;
            }
            cookies[key] = split[1];
        }
    });
    return function()
    {
        delete document.cookie;
        for(var key in cookies)
        {
            document.cookie = key + '=' + cookies[key];
        }
    };
}

var detach = hijackCookies();

// Do something with cookies or let 3rd party code run
// ...

detach();

      

[ Fiddle ] (Note: Reloading the entire page and hitting "run" is not the same thing!)

Tested on Firefox 38.0.1 and Chrome 42.0.2311.152.

+1


source







All Articles