@ -19,8 +19,6 @@
Home : https : //github.com/gorhill/uMatrix
Home : https : //github.com/gorhill/uMatrix
* /
* /
/* jshint boss: true */
'use strict' ;
'use strict' ;
/******************************************************************************/
/******************************************************************************/
@ -75,6 +73,13 @@ var onBeforeRootFrameRequestHandler = function(details) {
// Intercept and filter web requests according to white and black lists.
// Intercept and filter web requests according to white and black lists.
var onBeforeRequestHandler = function ( details ) {
var onBeforeRequestHandler = function ( details ) {
var µm = µMatrix ,
µmuri = µm . URI ,
requestURL = details . url ,
requestScheme = µmuri . schemeFromURI ( requestURL ) ;
if ( µmuri . isNetworkScheme ( requestScheme ) === false ) { return ; }
var requestType = requestTypeNormalizer [ details . type ] || 'other' ;
var requestType = requestTypeNormalizer [ details . type ] || 'other' ;
// https://github.com/gorhill/httpswitchboard/issues/303
// https://github.com/gorhill/httpswitchboard/issues/303
@ -84,17 +89,6 @@ var onBeforeRequestHandler = function(details) {
return onBeforeRootFrameRequestHandler ( details ) ;
return onBeforeRootFrameRequestHandler ( details ) ;
}
}
var µm = µMatrix ,
µmuri = µm . URI ,
requestURL = details . url ,
requestScheme = µmuri . schemeFromURI ( requestURL ) ;
// Ignore non-network schemes
if ( µmuri . isNetworkScheme ( requestScheme ) === false ) {
µm . logger . writeOne ( '' , 'info' , 'request not processed: ' + requestURL ) ;
return ;
}
// Re-classify orphan HTTP requests as behind-the-scene requests. There is
// Re-classify orphan HTTP requests as behind-the-scene requests. There is
// not much else which can be done, because there are URLs
// not much else which can be done, because there are URLs
// which cannot be handled by µMatrix, i.e. `opera://startpage`,
// which cannot be handled by µMatrix, i.e. `opera://startpage`,
@ -148,12 +142,13 @@ var onBeforeRequestHandler = function(details) {
// Sanitize outgoing headers as per user settings.
// Sanitize outgoing headers as per user settings.
var onBeforeSendHeadersHandler = function ( details ) {
var onBeforeSendHeadersHandler = function ( details ) {
var µm = µMatrix ;
var µm = µMatrix ,
µmuri = µm . URI ,
requestURL = details . url ,
requestScheme = µmuri . schemeFromURI ( requestURL ) ;
// Ignore non-network schemes
// Ignore non-network schemes
if ( µm . URI . isNetworkScheme ( details . url ) === false ) {
return ;
}
if ( µmuri . isNetworkScheme ( requestScheme ) === false ) { return ; }
// Re-classify orphan HTTP requests as behind-the-scene requests. There is
// Re-classify orphan HTTP requests as behind-the-scene requests. There is
// not much else which can be done, because there are URLs
// not much else which can be done, because there are URLs
@ -162,8 +157,11 @@ var onBeforeSendHeadersHandler = function(details) {
// to scope on unknown scheme? Etc.
// to scope on unknown scheme? Etc.
// https://github.com/gorhill/httpswitchboard/issues/191
// https://github.com/gorhill/httpswitchboard/issues/191
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
// https://github.com/gorhill/httpswitchboard/issues/91#issuecomment-37180275
var pageStore = µm . mustPageStoreFromTabId ( details . tabId ) ;
var tabId = pageStore . tabId ;
var tabId = details . tabId ,
pageStore = µm . mustPageStoreFromTabId ( tabId ) ,
requestType = requestTypeNormalizer [ details . type ] || 'other' ,
requestHeaders = details . requestHeaders ,
headerIndex , headerValue ;
// https://github.com/gorhill/httpswitchboard/issues/342
// https://github.com/gorhill/httpswitchboard/issues/342
// Is this hyperlink auditing?
// Is this hyperlink auditing?
@ -186,13 +184,12 @@ var onBeforeSendHeadersHandler = function(details) {
// With hyperlink-auditing, removing header(s) is pointless, the whole
// With hyperlink-auditing, removing header(s) is pointless, the whole
// request must be cancelled.
// request must be cancelled.
var requestURL = details . url ;
var requestType = requestTypeNormalizer [ details . type ] || 'other' ;
if ( requestType === 'ping' ) {
var linkAuditor = details . requestHeaders . getHeader ( 'ping-to' ) ;
if ( linkAuditor !== '' ) {
headerIndex = headerIndexFromName ( 'ping-to' , requestHeaders ) ;
if ( headerIndex !== - 1 ) {
headerValue = requestHeaders [ headerIndex ] . value ;
if ( headerValue !== '' ) {
var block = µm . userSettings . processHyperlinkAuditing ;
var block = µm . userSettings . processHyperlinkAuditing ;
pageStore . recordRequest ( 'other' , requestURL + '{Ping-To:' + linkAuditor + '}' , block ) ;
pageStore . recordRequest ( 'other' , requestURL + '{Ping-To:' + headerValue + '}' , block ) ;
µm . logger . writeOne ( tabId , 'net' , '' , requestURL , 'ping' , block ) ;
µm . logger . writeOne ( tabId , 'net' , '' , requestURL , 'ping' , block ) ;
if ( block ) {
if ( block ) {
µm . hyperlinkAuditingFoiledCounter += 1 ;
µm . hyperlinkAuditingFoiledCounter += 1 ;
@ -203,43 +200,31 @@ var onBeforeSendHeadersHandler = function(details) {
// If we reach this point, request is not blocked, so what is left to do
// If we reach this point, request is not blocked, so what is left to do
// is to sanitize headers.
// is to sanitize headers.
var requestHostname = µm . URI . hostnameFromURI ( requestURL ) ;
if ( µm . mustBlock ( pageStore . pageHostname , requestHostname , 'cookie' ) ) {
if ( details . requestHeaders . setHeader ( 'cookie' , '' ) ) {
µm . cookieHeaderFoiledCounter ++ ;
}
}
if ( µm . tMatrix . evaluateSwitchZ ( 'referrer-spoof' , pageStore . pageHostname ) ) {
foilRefererHeaders ( µm , requestHostname , details ) ;
}
} ;
var rootHostname = pageStore . pageHostname ,
requestHostname = µmuri . hostnameFromURI ( requestURL ) ,
modified = false ;
/******************************************************************************/
// Process `Cookie` header.
var foilRefererHeaders = function ( µm , toHostname , details ) {
var foiled = false ;
var µmuri = µm . URI ;
var scheme = '' ;
var toDomain = '' ;
var referer = details . requestHeaders . getHeader ( 'referer' ) ;
if ( referer !== '' ) {
toDomain = toDomain || µmuri . domainFromHostname ( toHostname ) ;
if ( toDomain !== µmuri . domainFromURI ( referer ) ) {
scheme = scheme || µmuri . schemeFromURI ( details . url ) ;
//console.debug('foilRefererHeaders()> foiled referer for "%s"', details.url);
//console.debug('\treferrer "%s"', header.value);
// https://github.com/gorhill/httpswitchboard/issues/222#issuecomment-44828402
details . requestHeaders . setHeader (
'referer' ,
scheme + '://' + toHostname + '/'
) ;
foiled = true ;
headerIndex = headerIndexFromName ( 'cookie' , requestHeaders ) ;
if (
headerIndex !== - 1 &&
µm . mustBlock ( rootHostname , requestHostname , 'cookie' )
) {
headerValue = requestHeaders [ headerIndex ] . value ;
requestHeaders . splice ( headerIndex , 1 ) ;
modified = true ;
µm . cookieHeaderFoiledCounter ++ ;
if ( requestType === 'doc' ) {
µm . logger . writeOne ( tabId , 'net' , '' , headerValue , 'COOKIE' , true ) ;
}
}
}
}
// Process `Referer` header.
// https://github.com/gorhill/httpswitchboard/issues/222#issuecomment-44828402
// https://github.com/gorhill/uMatrix/issues/320
// https://github.com/gorhill/uMatrix/issues/320
// http://tools.ietf.org/html/rfc6454#section-7.3
// http://tools.ietf.org/html/rfc6454#section-7.3
// "The user agent MAY include an Origin header field in any HTTP
// "The user agent MAY include an Origin header field in any HTTP
@ -253,23 +238,29 @@ var foilRefererHeaders = function(µm, toHostname, details) {
// https://github.com/gorhill/uMatrix/issues/358
// https://github.com/gorhill/uMatrix/issues/358
// Do not spoof `Origin` header for the time being. This will be revisited.
// Do not spoof `Origin` header for the time being. This will be revisited.
//var origin = details.requestHeaders.getHeader('origin');
//if ( origin !== '' && origin !== 'null' ) {
// toDomain = toDomain || µmuri.domainFromHostname(toHostname);
// if ( toDomain !== µmuri.domainFromURI(origin) ) {
// scheme = scheme || µmuri.schemeFromURI(details.url);
// //console.debug('foilRefererHeaders()> foiled origin for "%s"', details.url);
// //console.debug('\torigin "%s"', header.value);
// details.requestHeaders.setHeader(
// 'origin',
// scheme + '://' + toHostname
// );
// foiled = true;
// }
//}
if ( foiled ) {
µm . refererHeaderFoiledCounter ++ ;
headerIndex = headerIndexFromName ( 'referer' , requestHeaders ) ;
if ( headerIndex !== - 1 ) {
headerValue = requestHeaders [ headerIndex ] . value ;
if (
headerValue !== '' &&
µm . tMatrix . evaluateSwitchZ ( 'referrer-spoof' , rootHostname )
) {
var toDomain = µmuri . domainFromHostname ( requestHostname ) ;
if ( toDomain !== '' && toDomain !== µmuri . domainFromURI ( headerValue ) ) {
var newValue = requestScheme + '://' + requestHostname + '/' ;
requestHeaders [ headerIndex ] . value = newValue ;
modified = true ;
µm . refererHeaderFoiledCounter ++ ;
if ( requestType === 'doc' ) {
µm . logger . writeOne ( tabId , 'net' , '' , headerValue , 'REFERER' , true ) ;
µm . logger . writeOne ( tabId , 'net' , '' , newValue , 'REFERER' , false ) ;
}
}
}
}
if ( modified ) {
return { requestHeaders : requestHeaders } ;
}
}
} ;
} ;