1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-07-19 11:18:42 +02:00

Fix timing issue with cached redirection to web accessible resources

Reported internally by @gwarser.

In rare occasion, a timing issue could cause uBO to redirect
to a web accessible resource meant to be used for another
network request. This is a regression introduced with the
following commit:

- 2e5d32e967

Additionally, I identified another issue which would cause
cached redirection to fail when a cache entry with redirection
to a web accessible resource was being reused, an issue which
could especially affect pages which are generated dynamically
(i.e. without full page reload).
This commit is contained in:
Raymond Hill 2020-11-10 10:43:26 -05:00
parent fd419cf0a3
commit 8985376b00
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
4 changed files with 27 additions and 21 deletions

View File

@ -1169,7 +1169,7 @@ vAPI.warSecret = (( ) => {
lastSecretTime = Date.now(); lastSecretTime = Date.now();
const secret = generateSecret(); const secret = generateSecret();
secrets.push(secret); secrets.push(secret);
return `?secret=${secret}`; return secret;
}; };
})(); })();

View File

@ -748,7 +748,7 @@ const onMessage = function(request, sender, callback) {
mouse: µb.epickerArgs.mouse, mouse: µb.epickerArgs.mouse,
zap: µb.epickerArgs.zap, zap: µb.epickerArgs.zap,
eprom: µb.epickerArgs.eprom, eprom: µb.epickerArgs.eprom,
pickerURL: vAPI.getURL(`/web_accessible_resources/epicker-ui.html${vAPI.warSecret()}`), pickerURL: vAPI.getURL(`/web_accessible_resources/epicker-ui.html?secret=${vAPI.warSecret()}`),
}; };
µb.epickerArgs.target = ''; µb.epickerArgs.target = '';
break; break;

View File

@ -134,11 +134,23 @@ const NetFilteringResultCache = class {
} }
lookupResult(fctxt) { lookupResult(fctxt) {
return this.results.get( const entry = this.results.get(
fctxt.getDocHostname() + ' ' + fctxt.getDocHostname() + ' ' +
fctxt.type + ' ' + fctxt.type + ' ' +
fctxt.url fctxt.url
); );
if ( entry === undefined ) { return; }
// We need to use a new WAR secret if one is present since WAR secrets
// can only be used once.
if (
entry.redirectURL !== undefined &&
entry.redirectURL.startsWith(this.extensionOriginURL)
) {
const redirectURL = new URL(entry.redirectURL);
redirectURL.searchParams.set('secret', vAPI.warSecret());
entry.redirectURL = redirectURL.href;
}
return entry;
} }
lookupAllBlocked(hostname) { lookupAllBlocked(hostname) {
@ -158,6 +170,7 @@ const NetFilteringResultCache = class {
}; };
NetFilteringResultCache.prototype.shelfLife = 15000; NetFilteringResultCache.prototype.shelfLife = 15000;
NetFilteringResultCache.prototype.extensionOriginURL = vAPI.getURL('/');
/******************************************************************************/ /******************************************************************************/
@ -267,18 +280,6 @@ const PageStore = class {
this.frames = new Map(); this.frames = new Map();
this.setFrameURL(0, tabContext.rawURL); this.setFrameURL(0, tabContext.rawURL);
// The current filtering context is cloned because:
// - We may be called with or without the current context having been
// initialized.
// - If it has been initialized, we do not want to change the state
// of the current context.
const fctxt = µb.logger.enabled
? µb.filteringContext
.duplicate()
.fromTabId(tabId)
.setURL(tabContext.rawURL)
: undefined;
// https://github.com/uBlockOrigin/uBlock-issues/issues/314 // https://github.com/uBlockOrigin/uBlock-issues/issues/314
const masterSwitch = tabContext.getNetFilteringSwitch(); const masterSwitch = tabContext.getNetFilteringSwitch();
@ -292,7 +293,11 @@ const PageStore = class {
µb.logger.enabled && µb.logger.enabled &&
context === 'tabCommitted' context === 'tabCommitted'
) { ) {
fctxt.setRealm('cosmetic') µb.filteringContext
.duplicate()
.fromTabId(tabId)
.setURL(tabContext.rawURL)
.setRealm('cosmetic')
.setType('dom') .setType('dom')
.setFilter(µb.sessionSwitches.toLogData()) .setFilter(µb.sessionSwitches.toLogData())
.toLogger(); .toLogger();
@ -540,6 +545,7 @@ const PageStore = class {
filterRequest(fctxt) { filterRequest(fctxt) {
fctxt.filter = undefined; fctxt.filter = undefined;
fctxt.redirectURL = undefined;
if ( this.getNetFilteringSwitch(fctxt) === false ) { if ( this.getNetFilteringSwitch(fctxt) === false ) {
return 0; return 0;

View File

@ -212,7 +212,7 @@ const RedirectEntry = class {
fctxt instanceof Object && fctxt instanceof Object &&
fctxt.type !== 'xmlhttprequest' fctxt.type !== 'xmlhttprequest'
) { ) {
let url = `${this.warURL}${vAPI.warSecret()}`; let url = `${this.warURL}?secret=${vAPI.warSecret()}`;
if ( this.params !== undefined ) { if ( this.params !== undefined ) {
for ( const name of this.params ) { for ( const name of this.params ) {
const value = fctxt[name]; const value = fctxt[name];
@ -489,7 +489,7 @@ RedirectEngine.prototype.loadBuiltinResources = function() {
} }
fetches.push( fetches.push(
µBlock.assets.fetch( µBlock.assets.fetch(
`/web_accessible_resources/${name}${vAPI.warSecret()}`, `/web_accessible_resources/${name}?secret=${vAPI.warSecret()}`,
{ responseType: details.data } { responseType: details.data }
).then( ).then(
result => process(result) result => process(result)