Skip to content

Commit

Permalink
Web accessible secrets can be used for at most one second
Browse files Browse the repository at this point in the history
Related issue:
- uBlockOrigin/uBlock-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:
- gorhill#2823
  • Loading branch information
gorhill committed Apr 30, 2019
1 parent 2cc60fb commit 9e43852
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 14 deletions.
47 changes: 35 additions & 12 deletions platform/chromium/vapi-background.js
Original file line number Diff line number Diff line change
Expand Up @@ -1035,22 +1035,33 @@ vAPI.messaging.broadcast = function(message) {

// https://github.com/gorhill/uBlock/issues/3474
// 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.
// 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 =
Math.floor(Math.random() * 982451653 + 982451653).toString(36) +
Math.floor(Math.random() * 982451653 + 982451653).toString(36);

var key = 'secret=' + vAPI.warSecret;
var root = vAPI.getURL('/');
var guard = function(details) {
if ( details.url.indexOf(key) === -1 ) {
return { redirectUrl: root };
vAPI.warSecret = (function() {
let lastSecretTime = 0;

const generateSecret = ( ) => {
lastSecretTime = Date.now();
return Math.floor(Math.random() * 982451653 + 982451653).toString(36) +
Math.floor(Math.random() * 982451653 + 982451653).toString(36);
};

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(
Expand All @@ -1060,6 +1071,18 @@ vAPI.messaging.broadcast = function(message) {
},
[ '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 = {
Expand Down
4 changes: 2 additions & 2 deletions src/js/redirect-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const warResolve = (function() {
};

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

0 comments on commit 9e43852

Please sign in to comment.