Skip to content

Commit a16e416

Browse files
committed
Fine tune hostname uncloaking through CNAME-lookup
Related issue: - uBlockOrigin/uBlock-issues#780 Related commit: - 3a564c199260 This adds two new advanced settings: - cnameIgnoreRootDocument - Default to `true` - Tells uBO to skip CNAME-lookup for root document. - cnameReplayFullURL - Default to `false` - Tells uBO whether to replay the whole URL or just the origin part of it. Replaying only the origin part is meant to lower undue breakage and improve performance by avoiding repeating the pattern-matching of the whole URL -- which pattern-matching was most likely already accomplished with the original request. This commit is meant to explore enabling CNAME-lookup by default for the next stable release while: - Eliminating a development burden by removing the need to create a new filtering syntax to deal with undesirable CNAME-cloaked hostnames - Eliminating a filter list maintainer burden by removing the need to find/deal with all base domains which engage in undesirable CNAME-cloaked hostnames The hope is that the approach implemented in this commit should require at most a few unbreak rules with no further need for special filtering syntax or filter list maintance efforts.
1 parent a817c80 commit a16e416

File tree

9 files changed

+102
-39
lines changed

9 files changed

+102
-39
lines changed

platform/chromium/vapi-background.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,18 +1259,29 @@ vAPI.Net = class {
12591259
console.info('No requests found to benchmark');
12601260
return;
12611261
}
1262+
const mappedTypes = new Map([
1263+
[ 'document', 'main_frame' ],
1264+
[ 'subdocument', 'sub_frame' ],
1265+
]);
12621266
console.info('vAPI.net.onBeforeSuspendableRequest()...');
12631267
const t0 = self.performance.now();
12641268
const promises = [];
1269+
const details = {
1270+
documentUrl: '',
1271+
tabId: -1,
1272+
parentFrameId: -1,
1273+
frameId: 0,
1274+
type: '',
1275+
url: '',
1276+
};
12651277
for ( const request of requests ) {
1266-
const details = {
1267-
documentUrl: request.frameUrl,
1268-
tabId: Number.MAX_SAFE_INTEGER,
1269-
parentFrameId: -1,
1270-
frameId: 0,
1271-
type: request.cpt,
1272-
url: request.url,
1273-
};
1278+
details.documentUrl = request.frameUrl;
1279+
details.tabId = -1;
1280+
details.parentFrameId = -1;
1281+
details.frameId = 0;
1282+
details.type = mappedTypes.get(request.cpt) || request.cpt;
1283+
details.url = request.url;
1284+
if ( details.type === 'main_frame' ) { continue; }
12741285
promises.push(this.onBeforeSuspendableRequest(details));
12751286
}
12761287
return Promise.all(promises).then(results => {

platform/firefox/vapi-webrequest.js

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,20 @@
6363
this.cnames = new Map([ [ '', '' ] ]);
6464
this.cnameAliasList = null;
6565
this.cnameIgnoreList = null;
66-
this.url = new URL(vAPI.getURL('/'));
66+
this.cnameIgnore1stParty = true;
67+
this.cnameIgnoreRootDocument = true;
6768
this.cnameMaxTTL = 60;
69+
this.cnameReplayFullURL = false;
6870
this.cnameTimer = undefined;
6971
}
7072
setOptions(options) {
7173
super.setOptions(options);
7274
this.cnameAliasList = this.regexFromStrList(options.cnameAliasList);
7375
this.cnameIgnoreList = this.regexFromStrList(options.cnameIgnoreList);
74-
this.cnameIgnore1stParty = options.cnameIgnore1stParty === true;
76+
this.cnameIgnore1stParty = options.cnameIgnore1stParty !== false;
77+
this.cnameIgnoreRootDocument = options.cnameIgnoreRootDocument !== false;
7578
this.cnameMaxTTL = options.cnameMaxTTL || 120;
79+
this.cnameReplayFullURL = options.cnameReplayFullURL === true;
7680
this.cnames.clear(); this.cnames.set('', '');
7781
}
7882
normalizeDetails(details) {
@@ -123,11 +127,22 @@
123127
}
124128
return Array.from(out);
125129
}
126-
processCanonicalName(cname, details) {
127-
this.url.href = details.url;
128-
details.cnameOf = this.url.hostname;
129-
this.url.hostname = cname;
130-
details.url = this.url.href;
130+
processCanonicalName(hn, cn, details) {
131+
const hnBeg = details.url.indexOf(hn);
132+
if ( hnBeg === -1 ) { return; }
133+
const oldURL = details.url;
134+
let newURL = oldURL.slice(0, hnBeg) + cn;
135+
const hnEnd = hnBeg + hn.length;
136+
if ( this.cnameReplayFullURL ) {
137+
newURL += oldURL.slice(hnEnd);
138+
} else {
139+
const pathBeg = oldURL.indexOf('/', hnEnd);
140+
if ( pathBeg !== -1 ) {
141+
newURL += oldURL.slice(hnEnd, pathBeg + 1);
142+
}
143+
}
144+
details.url = newURL;
145+
details.aliasURL = oldURL;
131146
return super.onBeforeSuspendableRequest(details);
132147
}
133148
recordCanonicalName(hn, record) {
@@ -187,11 +202,14 @@
187202
let r = super.onBeforeSuspendableRequest(details);
188203
if ( r !== undefined ) { return r; }
189204
if ( this.cnameAliasList === null ) { return; }
205+
if ( details.type === 'main_frame' && this.cnameIgnoreRootDocument ) {
206+
return;
207+
}
190208
const hn = vAPI.hostnameFromNetworkURL(details.url);
191209
let cname = this.cnames.get(hn);
192210
if ( cname === '' ) { return; }
193211
if ( cname !== undefined ) {
194-
return this.processCanonicalName(cname, details);
212+
return this.processCanonicalName(hn, cname, details);
195213
}
196214
if ( this.cnameAliasList.test(hn) === false ) {
197215
this.cnames.set(hn, '');
@@ -201,7 +219,7 @@
201219
rec => {
202220
const cname = this.recordCanonicalName(hn, rec);
203221
if ( cname === '' ) { return; }
204-
return this.processCanonicalName(cname, details);
222+
return this.processCanonicalName(hn, cname, details);
205223
},
206224
( ) => {
207225
this.cnames.set(hn, '');

src/css/logger-ui.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ body.colorBlind #vwRenderer .logEntry > div.cosmeticRealm,
268268
body.colorBlind #vwRenderer .logEntry > div.redirect {
269269
background-color: rgba(0, 19, 110, 0.1);
270270
}
271-
#vwRenderer .logEntry > div[data-cnameof] {
271+
#vwRenderer .logEntry > div[data-aliasid] {
272272
color: mediumblue;
273273
}
274274
#vwRenderer .logEntry > div[data-type="tabLoad"] {

src/js/background.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ const µBlock = (( ) => { // jshint ignore:line
4949
cnameAliasList: 'unset',
5050
cnameIgnoreList: 'unset',
5151
cnameIgnore1stParty: true,
52+
cnameIgnoreRootDocument: true,
5253
cnameMaxTTL: 120,
54+
cnameReplayFullURL: false,
5355
consoleLogLevel: 'unset',
5456
debugScriptlets: false,
5557
debugScriptletInjector: false,

src/js/filtering-context.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929
}
3030
this.tstamp = 0;
3131
this.realm = '';
32+
this.id = undefined;
3233
this.type = undefined;
33-
this.cnameOf = undefined;
3434
this.url = undefined;
35+
this.aliasURL = undefined;
3536
this.hostname = undefined;
3637
this.domain = undefined;
3738
this.docId = undefined;
@@ -64,9 +65,10 @@
6465
}
6566
this.fromTabId(tabId);
6667
this.realm = '';
68+
this.id = details.requestId;
6769
this.type = details.type;
6870
this.setURL(details.url);
69-
this.cnameOf = details.cnameOf || undefined;
71+
this.aliasURL = details.aliasURL || undefined;
7072
this.docId = details.type !== 'sub_frame'
7173
? details.frameId
7274
: details.parentFrameId;

src/js/logger-ui.js

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,12 @@ const regexFromURLFilteringResult = function(result) {
157157

158158
const nodeFromURL = function(parent, url, re) {
159159
const fragment = document.createDocumentFragment();
160-
if ( re instanceof RegExp === false ) {
160+
if ( re === undefined ) {
161161
fragment.textContent = url;
162162
} else {
163+
if ( typeof re === 'string' ) {
164+
re = new RegExp(re.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g');
165+
}
163166
const matches = re.exec(url);
164167
if ( matches === null || matches[0].length === 0 ) {
165168
fragment.textContent = url;
@@ -211,6 +214,9 @@ const LogEntry = function(details) {
211214
this[prop] = details[prop];
212215
}
213216
}
217+
if ( details.aliasURL !== undefined ) {
218+
this.aliased = true;
219+
}
214220
if ( this.tabDomain === '' ) {
215221
this.tabDomain = this.tabHostname || '';
216222
}
@@ -222,12 +228,13 @@ const LogEntry = function(details) {
222228
}
223229
};
224230
LogEntry.prototype = {
225-
cnameOf: '',
231+
aliased: false,
226232
dead: false,
227233
docDomain: '',
228234
docHostname: '',
229235
domain: '',
230236
filter: undefined,
237+
id: '',
231238
realm: '',
232239
tabDomain: '',
233240
tabHostname: '',
@@ -294,7 +301,7 @@ const processLoggerEntries = function(response) {
294301
if ( autoDeleteVoidedRows ) { continue; }
295302
parsed.voided = true;
296303
}
297-
if ( parsed.type === 'main_frame' && parsed.cnameOf === '' ) {
304+
if ( parsed.type === 'main_frame' && parsed.aliased === false ) {
298305
const separator = createLogSeparator(parsed, unboxed.url);
299306
loggerEntries.unshift(separator);
300307
if ( rowFilterer.filterOne(separator) ) {
@@ -304,7 +311,7 @@ const processLoggerEntries = function(response) {
304311
}
305312
}
306313
}
307-
if ( cnameOfEnabled === false && parsed.cnameOf !== '' ) {
314+
if ( cnameOfEnabled === false && parsed.aliased ) {
308315
uDom.nodeFromId('filterExprCnameOf').style.display = '';
309316
cnameOfEnabled = true;
310317
}
@@ -405,8 +412,10 @@ const parseLogEntry = function(details) {
405412
textContent.push(normalizeToStr(details.url));
406413

407414
// Hidden cells -- useful for row-filtering purpose
408-
if ( entry.cnameOf !== '' ) {
409-
textContent.push(`cnameOf=${entry.cnameOf}`);
415+
416+
// Cell 7
417+
if ( entry.aliased ) {
418+
textContent.push(`aliasURL=${details.aliasURL}`);
410419
}
411420

412421
entry.textContent = textContent.join('\t');
@@ -723,17 +732,20 @@ const viewPort = (( ) => {
723732
span.textContent = cells[5];
724733

725734
// URL
726-
let re = null;
735+
let re;
727736
if ( filteringType === 'static' ) {
728737
re = new RegExp(filter.regex, 'gi');
729738
} else if ( filteringType === 'dynamicUrl' ) {
730739
re = regexFromURLFilteringResult(filter.rule.join(' '));
731740
}
732741
nodeFromURL(div.children[6], cells[6], re);
733742

734-
// Cname
735-
if ( details.cnameOf !== '' ) {
736-
div.setAttribute('data-cnameof', details.cnameOf);
743+
// Alias URL (CNAME, etc.)
744+
if ( cells.length > 7 ) {
745+
const pos = details.textContent.lastIndexOf('\taliasURL=');
746+
if ( pos !== -1 ) {
747+
div.setAttribute('data-aliasid', details.id);
748+
}
737749
}
738750

739751
return div;
@@ -1452,6 +1464,16 @@ const reloadTab = function(ev) {
14521464
return targetRow.children[1].textContent;
14531465
};
14541466

1467+
const aliasURLFromID = function(id) {
1468+
if ( id === '' ) { return ''; }
1469+
for ( const entry of loggerEntries ) {
1470+
if ( entry.id !== id || entry.aliased ) { continue; }
1471+
const fields = entry.textContent.split('\t');
1472+
return fields[6] || '';
1473+
}
1474+
return '';
1475+
};
1476+
14551477
const toSummaryPaneFilterNode = async function(receiver, filter) {
14561478
receiver.children[1].textContent = filter;
14571479
if ( filterAuthorMode !== true ) { return; }
@@ -1613,8 +1635,8 @@ const reloadTab = function(ev) {
16131635
rows[6].style.display = 'none';
16141636
}
16151637
// URL
1616-
text = trch[6].textContent;
1617-
if ( text !== '' ) {
1638+
const canonicalURL = trch[6].textContent;
1639+
if ( canonicalURL !== '' ) {
16181640
const attr = tr.getAttribute('data-status') || '';
16191641
if ( attr !== '' ) {
16201642
rows[7].setAttribute('data-status', attr);
@@ -1623,12 +1645,17 @@ const reloadTab = function(ev) {
16231645
} else {
16241646
rows[7].style.display = 'none';
16251647
}
1626-
// CNAME of
1627-
text = tr.getAttribute('data-cnameof') || '';
1628-
if ( text !== '' ) {
1629-
rows[8].children[1].textContent = text;
1648+
// Alias URL
1649+
text = tr.getAttribute('data-aliasid');
1650+
const aliasURL = text ? aliasURLFromID(text) : '';
1651+
if ( aliasURL !== '' ) {
1652+
rows[8].children[1].textContent =
1653+
vAPI.hostnameFromURI(aliasURL) + ' \u21d2\n\u2003' +
1654+
vAPI.hostnameFromURI(canonicalURL);
1655+
rows[9].children[1].textContent = aliasURL;
16301656
} else {
16311657
rows[8].style.display = 'none';
1658+
rows[9].style.display = 'none';
16321659
}
16331660
};
16341661

src/js/storage.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ self.addEventListener('hiddenSettingsChanged', ( ) => {
139139
cnameAliasList: µBlock.hiddenSettings.cnameAliasList,
140140
cnameIgnoreList: µBlock.hiddenSettings.cnameIgnoreList,
141141
cnameIgnore1stParty: µBlock.hiddenSettings.cnameIgnore1stParty,
142+
cnameIgnoreRootDocument: µBlock.hiddenSettings.cnameIgnoreRootDocument,
142143
cnameMaxTTL: µBlock.hiddenSettings.cnameMaxTTL,
144+
cnameReplayFullURL: µBlock.hiddenSettings.cnameReplayFullURL,
143145
});
144146
});
145147

src/js/traffic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const onBeforeRequest = function(details) {
9999
if (
100100
details.parentFrameId !== -1 &&
101101
details.type === 'sub_frame' &&
102-
details.cnameOf === undefined
102+
details.aliasURL === undefined
103103
) {
104104
pageStore.setFrame(details.frameId, details.url);
105105
}

src/logger-ui.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
</span>
6666
</div>
6767
<div><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\t(?:0,)?1\t" data-i18n="loggerRowFiltererBuiltin1p"></span><span data-filtex="\t(?:3(?:,\d)?|0,3)\t" data-i18n="loggerRowFiltererBuiltin3p"></span></div>
68-
<div id="filterExprCnameOf" style="display:none"><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\tcnameOf=.">CNAME</span></div>
68+
<div id="filterExprCnameOf" style="display:none"><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\taliasURL=.">CNAME</span></div>
6969
</div>
7070
</span>
7171
</span>
@@ -121,7 +121,8 @@
121121
<div><span data-i18n="loggerEntryDetailsPartyness"></span><span class="prose"></span></div>
122122
<div><span data-i18n="loggerEntryDetailsType"></span><span></span></div>
123123
<div><span data-i18n="loggerEntryDetailsURL"></span><span></span></div>
124-
<div><span >CNAME of</span><span></span></div>
124+
<div><span>CNAME</span><span></span></div>
125+
<div><span>Original URL</span><span></span></div>
125126
</div>
126127
<div class="pane dynamic hide" data-pane="dynamic">
127128
<div class="toolbar row">

0 commit comments

Comments
 (0)