Web accessible secrets can be used for at most one second

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/550

Related Chromium issue (I can't access it):
- https://bugs.chromium.org/p/chromium/issues/detail?id=957866

Findings so far: affects browsers based on Chromium 74.
I could not reproduce the issue with either Chromium 73 or
Google Chrome 75.

This commit is a mitigation: to prevent sites from using
uBO's internal WAR secret for tracking purpose. A secret
can be used for at most one second, after which a new secret
is generated.

The original issue related to the implementation of
secret-gated web accessible resources is:
- https://github.com/gorhill/uBlock/issues/2823
This commit is contained in:
Raymond Hill 2019-04-30 14:36:07 -04:00
parent 2cc60fb6e8
commit 9e4385243c
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
2 changed files with 36 additions and 13 deletions

View file

@ -1035,22 +1035,33 @@ vAPI.messaging.broadcast = function(message) {
// https://github.com/gorhill/uBlock/issues/3474 // https://github.com/gorhill/uBlock/issues/3474
// https://github.com/gorhill/uBlock/issues/2823 // https://github.com/gorhill/uBlock/issues/2823
// - foil ability of web pages to identify uBO through // Foil ability of web pages to identify uBO through
// its web accessible resources. // its web accessible resources.
// https://github.com/gorhill/uBlock/issues/3497 // https://github.com/gorhill/uBlock/issues/3497
// - prevent web pages from interfering with uBO's element picker // Prevent web pages from interfering with uBO's element picker
// https://github.com/uBlockOrigin/uBlock-issues/issues/550
// A specific secret can be used for at most one second.
(function() { vAPI.warSecret = (function() {
vAPI.warSecret = let lastSecretTime = 0;
Math.floor(Math.random() * 982451653 + 982451653).toString(36) +
Math.floor(Math.random() * 982451653 + 982451653).toString(36);
var key = 'secret=' + vAPI.warSecret; const generateSecret = ( ) => {
var root = vAPI.getURL('/'); lastSecretTime = Date.now();
var guard = function(details) { return Math.floor(Math.random() * 982451653 + 982451653).toString(36) +
if ( details.url.indexOf(key) === -1 ) { Math.floor(Math.random() * 982451653 + 982451653).toString(36);
return { redirectUrl: root }; };
const secrets = [ generateSecret(), generateSecret(), generateSecret() ];
const root = vAPI.getURL('/');
const guard = function(details) {
const url = details.url;
for ( let i = 0, n = secrets.length; i < n; i++ ) {
if ( url.indexOf(`?secret=${secrets[i]}`) !== -1 ) {
return;
}
} }
return { redirectUrl: root };
}; };
chrome.webRequest.onBeforeRequest.addListener( chrome.webRequest.onBeforeRequest.addListener(
@ -1060,6 +1071,18 @@ vAPI.messaging.broadcast = function(message) {
}, },
[ 'blocking' ] [ 'blocking' ]
); );
return ( ) => {
const n = Math.min(
Math.floor((Date.now() - lastSecretTime) / 1000),
secrets.length
);
for ( let i = 0; i < n; i++ ) {
secrets.pop();
secrets.unshift(generateSecret());
}
return `?secret=${secrets[0]}`;
};
})(); })();
vAPI.net = { vAPI.net = {

View file

@ -64,7 +64,7 @@ const warResolve = (function() {
}; };
µBlock.assets.fetchText( µBlock.assets.fetchText(
`/web_accessible_resources/imported.txt?secret=${vAPI.warSecret}`, `/web_accessible_resources/imported.txt${vAPI.warSecret()}`,
onPairsLoaded onPairsLoaded
); );
}; };
@ -105,7 +105,7 @@ RedirectEntry.prototype.toURL = function(fctxt) {
fctxt.url.startsWith('https:') fctxt.url.startsWith('https:')
) )
) { ) {
return this.warURL + '?secret=' + vAPI.warSecret; return `${this.warURL}${vAPI.warSecret()}`;
} }
if ( this.data.startsWith('data:') === false ) { if ( this.data.startsWith('data:') === false ) {
if ( this.mime.indexOf(';') === -1 ) { if ( this.mime.indexOf(';') === -1 ) {