EFForg/privacybadger

Privacy Badger not setting navigator.globalPrivacyControl before scripts in the head block execute

Opened this issue · 5 comments

PrivacyBadger doesn't set navigator.globalPrivacyControl before scripts in the <head> block execute. This means that any scripts invoked in the <head> block, which is common for privacy control software like OneTrust, are not able to detect the signal. This is not a problem with other extensions, such as gpcEnabler.

I was able to replicate the issue by simply adding <script>window._isGpcSet = !!navigator.globalPrivacyControl;</script> immediately after the <head> tag in a web page. The value is ALWAYS false with PrivacyBadger, but true with native GPC support enabled in Firefox or Brave, and true with other extensions.

I did most of my testing with Chrome version 121.0.6167.85 using PrivacyBadger 2023.12.1 on MacOS.

Hello and thanks for opening an issue!

Do you have any example links where we might see this bug in action?

Nothing public, but I see it with something as simple as this:

<!DOCTYPE html><html>
<head><script>window._isGpcSet_head = !!window.navigator.globalPrivacyControl;</script></head>
<body>
<h2>Was GPC Detected?</h2>
<script>document.write('<p>GPC set in head block: ' + window._isGpcSet_head + '</p><p>GPC set in body block: ' + (!!window.navigator.globalPrivacyControl) + '</p><p>Typeof globalPrivacyControl: ' + typeof window.navigator.globalPrivacyControl + '</p>');</script>
</body>
</html>

I'll add that frequently the above shows false for the body as well. It appears the value being injected by PrivacyBadger may be delayed until after rendering?

OK, thank you for the example. I'm trying to assess the real world impact.

This should get fixed as part of updating to Manifest V3.

Just to add a bit more data, I built out the page above to add an interval timer to see how long it takes...

<!DOCTYPE html><html>
<head><script>window._isGpcSet_head = !!window.navigator.globalPrivacyControl;</script></head>
<body>
<h2>Was GPC Detected?</h2>
<script>document.write('<p>GPC set in head block: ' + window._isGpcSet_head + '</p><p>GPC set in body block: ' + (!!window.navigator.globalPrivacyControl) + '</p><p>Typeof globalPrivacyControl: ' + typeof window.navigator.globalPrivacyControl + '</p>');
document.write('<div id="gpcDiv"></div>');
window.inter = setInterval(function () {
    let gpc = !!window.navigator.globalPrivacyControl;
    let gd = document.getElementById('gpcDiv');
    gd.innerHTML += '<p>GPC = ' + gpc + ' at ' + new Date() + '</p>';
    if (gpc) { clearInterval(window.inter); }
}, 20);
</script>
</body>
</html>

For me, output like this is typical:

GPC = false at Fri Feb 02 2024 15:53:57 GMT-0500 (Eastern Standard Time)
GPC = false at Fri Feb 02 2024 15:53:57 GMT-0500 (Eastern Standard Time)
GPC = false at Fri Feb 02 2024 15:53:57 GMT-0500 (Eastern Standard Time)
GPC = false at Fri Feb 02 2024 15:53:57 GMT-0500 (Eastern Standard Time)
GPC = true at Fri Feb 02 2024 15:53:57 GMT-0500 (Eastern Standard Time)

So about 80-100 ms.

This should now be fixed in Privacy Badger for Chrome version 2024.5.30 and later.

The delay is still there in all other browsers for now.