From f985484d021ce46cf0dd6db4ff4412c14767f952 Mon Sep 17 00:00:00 2001 From: Konrad Dzwinel Date: Mon, 27 Sep 2021 12:24:09 +0200 Subject: [PATCH 1/8] New test page - https upgrade loop --- .../https-loop-protection/http-only.html | 36 +++++ .../https-loop-protection/index.html | 27 ++++ .../https-loop-protection/main.js | 142 ++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 privacy-protections/https-loop-protection/http-only.html create mode 100644 privacy-protections/https-loop-protection/index.html create mode 100644 privacy-protections/https-loop-protection/main.js diff --git a/privacy-protections/https-loop-protection/http-only.html b/privacy-protections/https-loop-protection/http-only.html new file mode 100644 index 0000000..e911810 --- /dev/null +++ b/privacy-protections/https-loop-protection/http-only.html @@ -0,0 +1,36 @@ + + + + + + HTTPS upgrade loop protection + + + + + \ No newline at end of file diff --git a/privacy-protections/https-loop-protection/index.html b/privacy-protections/https-loop-protection/index.html new file mode 100644 index 0000000..b0423ed --- /dev/null +++ b/privacy-protections/https-loop-protection/index.html @@ -0,0 +1,27 @@ + + + + + + HTTPS upgrade loop protection + + + + + +

[Home][Privacy Protections Tests][HTTPS Upgrade Loop Protection]

+ +

This tst will navigate to page on a https upgradable domain that imadiatelly redirects to its http version. This will cause a http↔http loop (client trying to upgrade, page downgrading). Clients should detect this scenario and allow page to load.

+ +

+ + + +

+ + + \ No newline at end of file diff --git a/privacy-protections/https-loop-protection/main.js b/privacy-protections/https-loop-protection/main.js new file mode 100644 index 0000000..b946172 --- /dev/null +++ b/privacy-protections/https-loop-protection/main.js @@ -0,0 +1,142 @@ +const startButton = document.querySelector('#start'); +const downloadButton = document.querySelector('#download'); + +const testsDiv = document.querySelector('#tests'); +const testsSummaryDiv = document.querySelector('#tests-summary'); +const testsDetailsDiv = document.querySelector('#tests-details'); + +const TEST_DOMAIN = 'good.third-party.site'; + +const tests = [ + { + id: 'upgrade-navigation', + run: () => { + let res; + const promise = new Promise((resolve, reject) => { res = resolve; }); + const otherWindow = window.open(`http://${TEST_DOMAIN}/privacy-protections/https-loop-protection/http-only.html`); + + const interval = setInterval(() => { + otherWindow.postMessage({ action: 'url', type: 'navigation' }, `http://${TEST_DOMAIN}/`); + otherWindow.postMessage({ action: 'url', type: 'navigation' }, `https://${TEST_DOMAIN}/`); + }, 500); + + function onMessage (m) { + if (m.data && m.data.type === 'navigation') { + clearInterval(interval); + otherWindow.close(); + window.removeEventListener('message', onMessage); + res(m.data.url); + } + } + + window.addEventListener('message', onMessage); + + return promise; + } + } +]; + +// object that contains results of all tests +const results = { + page: 'https-loop-protection', + date: null, + results: [] +}; + +function resultToHTML (data) { + if (Array.isArray(data)) { + return ``; + } else if (data) { + return JSON.stringify(data, null, 2); + } + + return null; +} + +/** + * Test runner + */ +function runTests () { + startButton.setAttribute('disabled', 'disabled'); + downloadButton.removeAttribute('disabled'); + testsDiv.removeAttribute('hidden'); + + results.results.length = 0; + results.date = (new Date()).toUTCString(); + let all = 0; + let failed = 0; + + testsDetailsDiv.innerHTML = ''; + + function updateSummary () { + testsSummaryDiv.innerText = `Performed ${all} tests${failed > 0 ? ` (${failed} failed)` : ''}. Click for details.`; + } + + for (const test of tests) { + const resultObj = { + id: test.id, + value: null + }; + results.results.push(resultObj); + + const li = document.createElement('li'); + li.id = `test-${test.id.replace(' ', '-')}`; + li.innerHTML = `${test.id} - `; + const valueSpan = li.querySelector('.value'); + + testsDetailsDiv.appendChild(li); + + try { + const result = test.run(); + + if (result instanceof Promise) { + result + .then(data => { + valueSpan.innerHTML = resultToHTML(data); + resultObj.value = data || null; + }) + .catch(e => { + failed++; + valueSpan.innerHTML = `❌ error thrown ("${e.message ? e.message : e}")`; + updateSummary(); + }); + } else { + valueSpan.innerHTML = resultToHTML(data); + resultObj.value = result || null; + } + } catch (e) { + failed++; + valueSpan.innerHTML = `❌ error thrown ("${e.message ? e.message : e}")`; + } + + all++; + } + + updateSummary(); + + startButton.removeAttribute('disabled'); +} + +function downloadTheResults () { + const data = JSON.stringify(results, null, 2); + const a = document.createElement('a'); + const url = window.URL.createObjectURL(new Blob([data], { type: 'application/json' })); + a.href = url; + a.download = 'https-loop-protection-results.json'; + + document.body.appendChild(a); + a.click(); + + window.URL.revokeObjectURL(url); + a.remove(); +} + +downloadButton.addEventListener('click', () => downloadTheResults()); + +// run tests if button was clicked or… +startButton.addEventListener('click', () => runTests()); + +// if url query is '?run' start tests imadiatelly +if (document.location.search === '?run') { + runTests(); +} From de534376b8514ca3878c82da5972b82f068f2cf4 Mon Sep 17 00:00:00 2001 From: Konrad Dzwinel Date: Mon, 27 Sep 2021 12:24:17 +0200 Subject: [PATCH 2/8] Unerlated nit fix --- privacy-protections/https-upgrades/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/privacy-protections/https-upgrades/main.js b/privacy-protections/https-upgrades/main.js index 15fe76e..dd4b558 100644 --- a/privacy-protections/https-upgrades/main.js +++ b/privacy-protections/https-upgrades/main.js @@ -174,7 +174,7 @@ function downloadTheResults () { const a = document.createElement('a'); const url = window.URL.createObjectURL(new Blob([data], { type: 'application/json' })); a.href = url; - a.download = 'fingerprinting-results.json'; + a.download = 'https-upgrades-results.json'; document.body.appendChild(a); a.click(); From dd934d2e2fff45ba54cb670407438b74aeccea38 Mon Sep 17 00:00:00 2001 From: Konrad Dzwinel Date: Mon, 27 Sep 2021 12:59:34 +0200 Subject: [PATCH 3/8] Hook it up to index pages --- index.html | 1 + privacy-protections/index.html | 1 + 2 files changed, 2 insertions(+) diff --git a/index.html b/index.html index a6cca54..8249f66 100644 --- a/index.html +++ b/index.html @@ -54,6 +54,7 @@

Privacy Protections Tests

  • Storage blocking
  • Referrer trimming
  • HTTPS upgrades
  • +
  • HTTPS upgrade loop protection
  • Facebook click to load
  • Surrogates
  • diff --git a/privacy-protections/index.html b/privacy-protections/index.html index 3eb5c69..21fbdee 100644 --- a/privacy-protections/index.html +++ b/privacy-protections/index.html @@ -17,6 +17,7 @@

    Privacy Protections Tests

  • Storage blocking
  • Referrer trimming
  • HTTPS upgrades
  • +
  • HTTPS upgrade loop protection
  • Facebook click to load
  • Surrogates
  • From 1025283b0108915080630da4e4cf07129f1f3758 Mon Sep 17 00:00:00 2001 From: Konrad Dzwinel Date: Mon, 27 Sep 2021 13:01:54 +0200 Subject: [PATCH 4/8] Missing styles. --- privacy-protections/https-loop-protection/style.css | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 privacy-protections/https-loop-protection/style.css diff --git a/privacy-protections/https-loop-protection/style.css b/privacy-protections/https-loop-protection/style.css new file mode 100644 index 0000000..060125f --- /dev/null +++ b/privacy-protections/https-loop-protection/style.css @@ -0,0 +1,7 @@ +* { + box-sizing: border-box; +} + +.value { + color: gray; +} \ No newline at end of file From bfaf0181320738bf6497ac5f21fdd59e6d3bd007 Mon Sep 17 00:00:00 2001 From: Konrad Dzwinel Date: Mon, 27 Sep 2021 13:06:52 +0200 Subject: [PATCH 5/8] Fix undefined --- privacy-protections/https-loop-protection/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/privacy-protections/https-loop-protection/main.js b/privacy-protections/https-loop-protection/main.js index b946172..e15cc8c 100644 --- a/privacy-protections/https-loop-protection/main.js +++ b/privacy-protections/https-loop-protection/main.js @@ -101,7 +101,7 @@ function runTests () { updateSummary(); }); } else { - valueSpan.innerHTML = resultToHTML(data); + valueSpan.innerHTML = resultToHTML(result); resultObj.value = result || null; } } catch (e) { From c48753fcb21e775809e2582d3ee3f145a2f58e3e Mon Sep 17 00:00:00 2001 From: Konrad Dzwinel Date: Wed, 29 Sep 2021 12:13:25 +0200 Subject: [PATCH 6/8] Store attempt # in storage not URL because protection will not kick in. --- .../https-loop-protection/http-only.html | 17 ++++++++++++++--- .../https-loop-protection/main.js | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/privacy-protections/https-loop-protection/http-only.html b/privacy-protections/https-loop-protection/http-only.html index e911810..3b44501 100644 --- a/privacy-protections/https-loop-protection/http-only.html +++ b/privacy-protections/https-loop-protection/http-only.html @@ -1,5 +1,6 @@ + @@ -8,17 +9,27 @@