xiMatrix

filter net requests according to source, destination and type  https://addons.mozilla.org/firefox/addon/ximatrix/
git clone https://git.ce9e.org/xiMatrix.git

commit
0d34234c977690e3ca07ddba7f3c120ce82ff3bd
parent
104bc45a770c0c09e7191bf5355b65627d743503
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2022-11-27 08:38
allow to disable recording

Recording is not relevant most of the time. We are currently running a
lot of code on each request just to record requests. With CSPs, this can
even trigger browser bugs (e.g. https://bugzilla.mozilla.org/show_bug.cgi?id=1459872)

Diffstat

M README.md 1 +
M src/bg.js 39 +++++++++++++++++++++++----------------
M src/popup.html 6 +++++-
M src/popup.js 6 ++++++

4 files changed, 35 insertions, 17 deletions


diff --git a/README.md b/README.md

@@ -14,6 +14,7 @@ to allow only those requests you want. Definitely for advanced users.
   14    14 	-	keyboard navigation
   15    15 	-	simpler code
   16    16 	-	rules are encoded as JSON
   -1    17 	-	recording requests can be disabled to improve performance
   17    18 	-	it is possible to control inline scripts, styles, and images
   18    19 	-	there is a separate column for fonts
   19    20 -	disadvantages / simplifications

diff --git a/src/bg.js b/src/bg.js

@@ -1,5 +1,7 @@
    1     1 /* global browser shared */
    2     2 
   -1     3 var recording = false;
   -1     4 
    3     5 var getHostname = function(url) {
    4     6     var u = new URL(url);
    5     7     return u.hostname;
@@ -47,6 +49,9 @@ var restrictRules = function(rules, context) {
   47    49 };
   48    50 
   49    51 var pushRequest = function(tabId, hostname, type) {
   -1    52     if (!recording) {
   -1    53         return Promise.resolve();
   -1    54     }
   50    55     return getRequests().then(requests => {
   51    56         if (!requests[tabId]) {
   52    57             requests[tabId] = {};
@@ -90,6 +95,7 @@ browser.runtime.onMessage.addListener((msg, sender) => {
   90    95                 context: context,
   91    96                 rules: restrictRules(rules, context),
   92    97                 requests: requests[tab.id] || {},
   -1    98                 recording: recording,
   93    99             };
   94   100         });
   95   101     } else if (msg.type === 'setRule') {
@@ -103,6 +109,9 @@ browser.runtime.onMessage.addListener((msg, sender) => {
  103   109         });
  104   110     } else if (msg.type === 'securitypolicyviolation') {
  105   111         return pushRequest(sender.tab.id, 'inline', msg.data);
   -1   112     } else if (msg.type === 'toggleRecording') {
   -1   113         recording = !recording;
   -1   114         return Promise.resolve(recording);
  106   115     }
  107   116 });
  108   117 
@@ -143,26 +152,24 @@ browser.webRequest.onHeadersReceived.addListener(function(details) {
  143   152     return getRules().then(rules => {
  144   153         var context = getHostname(details.url);
  145   154 
  146    -1         var header = type => {
   -1   155         var csp = (type, value) => {
   -1   156             var name = 'Content-Security-Policy';
  147   157             if (shared.shouldAllow(rules, context, 'inline', type)) {
  148    -1                 return 'Content-Security-Policy-Report-Only';
  149    -1             } else {
  150    -1                 return 'Content-Security-Policy';
   -1   158                 if (recording) {
   -1   159                     name = 'Content-Security-Policy-Report-Only';
   -1   160                 } else {
   -1   161                     return;
   -1   162                 }
  151   163             }
   -1   164             details.responseHeaders.push({
   -1   165                 name: name,
   -1   166                 value: value,
   -1   167             });
  152   168         };
  153   169 
  154    -1         details.responseHeaders.push({
  155    -1             name: header('css'),
  156    -1             value: "style-src 'self' *",
  157    -1         });
  158    -1         details.responseHeaders.push({
  159    -1             name: header('script'),
  160    -1             value: "script-src 'self' *",
  161    -1         });
  162    -1         details.responseHeaders.push({
  163    -1             name: header('media'),
  164    -1             value: "img-src 'self' *",
  165    -1         });
   -1   170         csp('css', "style-src 'self' *");
   -1   171         csp('script', "script-src 'self' *");
   -1   172         csp('media', "img-src 'self' *");
  166   173 
  167   174         return {
  168   175             responseHeaders: details.responseHeaders,

diff --git a/src/popup.html b/src/popup.html

@@ -6,10 +6,14 @@
    6     6 </head>
    7     7 <body>
    8     8 	<table></table>
   -1     9 	<label>
   -1    10 		<input type="checkbox" name="recording">
   -1    11 		recording
   -1    12 	</label>
    9    13 	<button type="button" name="settings">Edit rules</button>
   10    14 	<details>
   11    15 		<summary>Help</summary>
   12    -1 		<p>In the table above, the columns represent different types of requests. The rows represent domains. Numbers show how many requests of a given type the current tab tries to make to the given domain. Red cells are blocked, green cells are allowed. Light green cells are allowed indirectly, e.g. because they represent a sub-domain of an allowed domain. Grey cells are disabled.</p>
   -1    16 		<p>In the table above, the columns represent different types of requests. The rows represent domains. Numbers (if recording is enabled) show how many requests of a given type the current tab tries to make to the given domain. Red cells are blocked, green cells are allowed. Light green cells are allowed indirectly, e.g. because they represent a sub-domain of an allowed domain. Grey cells are disabled.</p>
   13    17 		<p>By default, everything is blocked. You can click on a cell to allow it. You can also click on the domain or type to allow the complete row or column. There are also some special rows:</p>
   14    18 		<ul>
   15    19 			<li><strong>inline</strong>: This row is in charge of blocking inline code, e.g. <code>&lt;script&gt;</code>-elements that are directly embedded into the HTML code. Note that some cells are disabled, e.g. there is no such thing as an "inline XHR".</li>

diff --git a/src/popup.js b/src/popup.js

@@ -5,6 +5,7 @@ var requests;
    5     5 var rules;
    6     6 
    7     7 var table = document.querySelector('table');
   -1     8 var recording = document.querySelector('[name="recording"]')
    8     9 
    9    10 var sendMessage = function(type, data) {
   10    11     return browser.runtime.sendMessage({type: type, data: data});
@@ -133,6 +134,7 @@ var loadContext = function(c) {
  133   134         context = data.context;
  134   135         requests = data.requests;
  135   136         rules = data.rules;
   -1   137         recording.checked = data.recording;
  136   138 
  137   139         table.innerHTML = '';
  138   140         table.append(createHeader());
@@ -156,3 +158,7 @@ document.querySelector('[name="settings"]').addEventListener('click', event => {
  156   158 document.addEventListener('DOMContentLoaded', () => {
  157   159     loadContext();
  158   160 });
   -1   161 
   -1   162 recording.addEventListener('change', event => {
   -1   163     sendMessage('toggleRecording');
   -1   164 });