diff --git a/README.md b/README.md index e2c79de..88e7e53 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,14 @@ Please note that we are not taking external contributions for new test pages, bu - Please remember to link new test page from [index.html](./index.html). - Once you have a PR with a new page please assign it to one of the AoR DRIs (@brindy, @kdzwinel). +### Test domains + +We have couple of test domains, that all resolve to `privacy-test-pages.glitch.me`, which help us simulate various scenarios: + +- `good.third-party.site` - non-tracking third party, it's not on our blocklist and will not be blocked by our clients +- `broken.third-party.site` - tracking third party that we can't block (e.g. due to brekage), it's on our blocklist, but it will not be blocked by our clients +- `bad.third-party.site` - tracking third party that's on our blocklist and our clients will block + ### How to test it locally If you are working on a simple page you can start any local server (e.g. `python -m SimpleHTTPServer 8000`) in the main folder of the project. diff --git a/privacy-protections/storage-blocking/3rdparty.js b/privacy-protections/storage-blocking/3rdparty.js index 347f60d..abffe6e 100644 --- a/privacy-protections/storage-blocking/3rdparty.js +++ b/privacy-protections/storage-blocking/3rdparty.js @@ -4,12 +4,17 @@ * As we load this script via a 3rd party origin in the test, when running `store` the 3rd party * origin will be visible in the call stack to document.cookie. */ -commonTests.push({ - id: 'JS cookie (3rd party script)', - store: (data) => { - document.cookie = `tpdata=${data}; expires= Wed, 21 Aug 2030 20:00:00 UTC;`; - }, - retrive: () => { - return document.cookie.match(/tpdata=([0-9]+)/)[1]; - } -}); +(function () { + const src = document.currentScript.src; + const trackingDomain = src.indexOf('https://broken.third-party.site/') === 0; + + commonTests.push({ + id: `JS cookie (3rd party ${trackingDomain ? 'tracking' : 'safe'} script)`, + store: (data) => { + document.cookie = `tp${trackingDomain ? 't' : 's'}data=${data}; expires= Wed, 21 Aug 2030 20:00:00 UTC;`; + }, + retrive: () => { + return trackingDomain ? document.cookie.match(/tptdata=([0-9]+)/)[1] : document.cookie.match(/tpsdata=([0-9]+)/)[1]; + } + }); +})(); diff --git a/privacy-protections/storage-blocking/index.html b/privacy-protections/storage-blocking/index.html index f7e5b5a..d72e41e 100644 --- a/privacy-protections/storage-blocking/index.html +++ b/privacy-protections/storage-blocking/index.html @@ -7,6 +7,7 @@ + @@ -27,4 +28,4 @@

- \ No newline at end of file + diff --git a/privacy-protections/storage-blocking/main.js b/privacy-protections/storage-blocking/main.js index 42eabec..4092d13 100644 --- a/privacy-protections/storage-blocking/main.js +++ b/privacy-protections/storage-blocking/main.js @@ -1,5 +1,6 @@ /* globals commonTests */ const THIRD_PARTY_ORIGIN = 'https://good.third-party.site'; +const THIRD_PARTY_TRACKER_ORIGIN = 'https://broken.third-party.site'; const storeButton = document.querySelector('#store'); const retriveButton = document.querySelector('#retrive'); @@ -16,51 +17,21 @@ const results = { results: [] }; -const tests = [ - { - id: 'header cookie', - store: (data) => { - return fetch(`/set-cookie?value=${data}`).then(r => { - if (!r.ok) { - throw new Error('Request failed.'); - } - }); - }, - retrive: () => { - return fetch('/reflect-headers') - .then(r => r.json()) - .then(data => data.headers.cookie.match(/headerdata=([0-9]+)/)[1]); - } - }, - { - id: 'third party header cookie', - store: (data) => { - return fetch(`${THIRD_PARTY_ORIGIN}/set-cookie?value=${data}`, { credentials: 'include' }).then(r => { - if (!r.ok) { - throw new Error('Request failed.'); - } - }); - }, - retrive: () => { - return fetch(`${THIRD_PARTY_ORIGIN}/reflect-headers`, { credentials: 'include' }) - .then(r => r.json()) - .then(data => data.headers.cookie.match(/headerdata=([0-9]+)/)[1]); - } - }, - { - id: 'third party iframe', +function create3pIframeTest (name, origin) { + return { + id: `${name} third party iframe`, store: (data) => { let res, rej; const promise = new Promise((resolve, reject) => { res = resolve; rej = reject; }); const iframe = document.createElement('iframe'); - iframe.src = `${THIRD_PARTY_ORIGIN}/privacy-protections/storage-blocking/iframe.html?data=${data}`; + iframe.src = `${origin}/privacy-protections/storage-blocking/iframe.html?data=${data}`; iframe.style.width = '10px'; iframe.style.height = '10px'; let failTimeout = null; function cleanUp (msg) { - if (msg.data) { + if (msg.origin === origin && msg.data) { res(msg.data); clearTimeout(failTimeout); @@ -83,7 +54,7 @@ const tests = [ const promise = new Promise((resolve, reject) => { res = resolve; rej = reject; }); const iframe = document.createElement('iframe'); - iframe.src = `${THIRD_PARTY_ORIGIN}/privacy-protections/storage-blocking/iframe.html`; + iframe.src = `${origin}/privacy-protections/storage-blocking/iframe.html`; iframe.style.width = '10px'; iframe.style.height = '10px'; let failTimeout = null; @@ -107,7 +78,57 @@ const tests = [ return promise; } + }; +} + +const tests = [ + { + id: 'first party header cookie', + store: (data) => { + return fetch(`/set-cookie?value=${data}`).then(r => { + if (!r.ok) { + throw new Error('Request failed.'); + } + }); + }, + retrive: () => { + return fetch('/reflect-headers') + .then(r => r.json()) + .then(data => data.headers.cookie.match(/headerdata=([0-9]+)/)[1]); + } + }, + { + id: 'safe third party header cookie', + store: (data) => { + return fetch(`${THIRD_PARTY_ORIGIN}/set-cookie?value=${data}`, { credentials: 'include' }).then(r => { + if (!r.ok) { + throw new Error('Request failed.'); + } + }); + }, + retrive: () => { + return fetch(`${THIRD_PARTY_ORIGIN}/reflect-headers`, { credentials: 'include' }) + .then(r => r.json()) + .then(data => data.headers.cookie.match(/headerdata=([0-9]+)/)[1]); + } + }, + { + id: 'tracking third party header cookie', + store: (data) => { + return fetch(`${THIRD_PARTY_TRACKER_ORIGIN}/set-cookie?value=${data}`, { credentials: 'include' }).then(r => { + if (!r.ok) { + throw new Error('Request failed.'); + } + }); + }, + retrive: () => { + return fetch(`${THIRD_PARTY_TRACKER_ORIGIN}/reflect-headers`, { credentials: 'include' }) + .then(r => r.json()) + .then(data => data.headers.cookie.match(/headerdata=([0-9]+)/)[1]); + } }, + create3pIframeTest('safe', THIRD_PARTY_ORIGIN), + create3pIframeTest('tracking', THIRD_PARTY_TRACKER_ORIGIN), { id: 'browser cache', store: (data) => {