ability to foil mixed content

pull/2/head
Raymond Hill 10 years ago
parent 5ba8f58094
commit 5e19edaab7

@ -90,7 +90,7 @@ var nameToSwitchStateMap = {
var switchBitOffsets = { var switchBitOffsets = {
'matrix-off': 0, 'matrix-off': 0,
'https-only': 2, 'https-strict': 2,
'ua-spoof-off': 4 'ua-spoof-off': 4
}; };

@ -173,11 +173,11 @@ var onBeforeChromeExtensionRequestHandler = function(details) {
} }
var µm = µMatrix; var µm = µMatrix;
// Is the target page still blacklisted?
var pageURL = decodeURIComponent(matches[1]); var pageURL = decodeURIComponent(matches[1]);
var hostname = decodeURIComponent(matches[2]); var pageHostname = decodeURIComponent(matches[2]);
if ( µm.mustBlock(µm.scopeFromURL(pageURL), hostname, 'doc') ) {
// Blacklisted as per matrix?
if ( µm.mustBlock(µm.scopeFromURL(pageURL), pageHostname, 'doc') ) {
return; return;
} }
@ -208,15 +208,16 @@ var onBeforeRootFrameRequestHandler = function(details) {
} }
var uri = µm.URI.set(details.url); var uri = µm.URI.set(details.url);
if ( uri.scheme !== 'http' && uri.scheme !== 'https' ) { if ( uri.scheme.indexOf('http') === -1 ) {
return; return;
} }
var requestURL = uri.normalizedURI(); var requestURL = uri.normalizedURI();
var requestHostname = uri.hostname; var requestHostname = uri.hostname;
var pageStats = µm.pageStatsFromTabId(tabId); var pageStore = µm.pageStatsFromTabId(tabId);
var pageURL = µm.pageUrlFromPageStats(pageStats);
var block = µm.mustBlock(pageStats.pageHostname, requestHostname, 'doc'); // Disallow request as per matrix?
var block = µm.mustBlock(pageStore.pageHostname, requestHostname, 'doc');
// console.debug('onBeforeRequestHandler()> block=%s "%s": %o', block, details.url, details); // console.debug('onBeforeRequestHandler()> block=%s "%s": %o', block, details.url, details);
@ -225,7 +226,7 @@ var onBeforeRootFrameRequestHandler = function(details) {
// rhill 2013-11-07: Senseless to do this for behind-the-scene requests. // rhill 2013-11-07: Senseless to do this for behind-the-scene requests.
// rhill 2013-12-03: Do this here only for root frames. // rhill 2013-12-03: Do this here only for root frames.
if ( tabId !== µm.behindTheSceneTabId ) { if ( tabId !== µm.behindTheSceneTabId ) {
µm.cookieHunter.recordPageCookies(pageStats); µm.cookieHunter.recordPageCookies(pageStore);
} }
return; return;
} }
@ -236,7 +237,7 @@ var onBeforeRootFrameRequestHandler = function(details) {
// requests, in order to ensure any potential redirects is reported // requests, in order to ensure any potential redirects is reported
// in proper chronological order. // in proper chronological order.
// https://github.com/gorhill/httpswitchboard/issues/112 // https://github.com/gorhill/httpswitchboard/issues/112
pageStats.recordRequest('doc', requestURL, block); pageStore.recordRequest('doc', requestURL, block);
// If it's a blacklisted frame, redirect to frame.html // If it's a blacklisted frame, redirect to frame.html
// rhill 2013-11-05: The root frame contains a link to noop.css, this // rhill 2013-11-05: The root frame contains a link to noop.css, this
@ -261,33 +262,31 @@ var onBeforeRootFrameRequestHandler = function(details) {
var processRequest = function(µm, details) { var processRequest = function(µm, details) {
var µmuri = µm.URI; var µmuri = µm.URI;
var requestType = requestTypeNormalizer[details.type];
var requestURL = µmuri.set(details.url).normalizedURI(); var requestURL = µmuri.set(details.url).normalizedURI();
var requestHostname = µmuri.hostname; var requestHostname = µmuri.hostname;
var requestPath = µmuri.path;
// rhill 2013-12-15:
// Try to transpose generic `other` category into something more
// meaningful.
var requestType = requestTypeNormalizer[details.type];
if ( requestType === 'other' ) {
requestType = µm.transposeType(requestType, µmuri.path);
}
// 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 HTTP Switchboard, i.e. `opera://startpage`, // which cannot be handled by µMatrix, i.e. `opera://startpage`,
// as this would lead to complications with no obvious solution, like how // as this would lead to complications with no obvious solution, like how
// 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 pageStats = µm.pageStatsFromTabId(details.tabId); var pageStore = µm.pageStatsFromTabId(details.tabId);
if ( !pageStats ) { if ( !pageStore ) {
pageStats = µm.pageStatsFromTabId(µm.behindTheSceneTabId); pageStore = µm.pageStatsFromTabId(µm.behindTheSceneTabId);
}
var pageURL = µm.pageUrlFromPageStats(pageStats);
// rhill 2013-12-15:
// Try to transpose generic `other` category into something more
// meaningful.
if ( requestType === 'other' ) {
requestType = µm.transposeType(requestType, requestPath);
} }
// Block request? // Disallow request as per temporary matrix?
var block = µm.mustBlock(pageStats.pageHostname, requestHostname, requestType); var block = µm.mustBlock(pageStore.pageHostname, requestHostname, requestType);
// Record request. // Record request.
// https://github.com/gorhill/httpswitchboard/issues/342 // https://github.com/gorhill/httpswitchboard/issues/342
@ -295,7 +294,7 @@ var processRequest = function(µm, details) {
// processing has already been performed, and that a synthetic URL has // processing has already been performed, and that a synthetic URL has
// been constructed for logging purpose. Use this synthetic URL if // been constructed for logging purpose. Use this synthetic URL if
// it is available. // it is available.
pageStats.recordRequest(requestType, details.µmRequestURL || requestURL, block); pageStore.recordRequest(requestType, details.µmRequestURL || requestURL, block);
// whitelisted? // whitelisted?
if ( !block ) { if ( !block ) {
@ -455,28 +454,29 @@ var onBeforeSendHeadersHandler = function(details) {
// 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 tabId = details.tabId; var tabId = details.tabId;
var pageStats = µm.pageStatsFromTabId(tabId); var pageStore = µm.pageStatsFromTabId(tabId);
if ( !pageStats ) { if ( !pageStore ) {
tabId = µm.behindTheSceneTabId; tabId = µm.behindTheSceneTabId;
pageStats = µm.pageStatsFromTabId(tabId); pageStore = µm.pageStatsFromTabId(tabId);
} }
var pageURL = µm.pageUrlFromPageStats(pageStats);
var reqHostname = µm.hostnameFromURL(requestURL); var reqHostname = µm.hostnameFromURL(requestURL);
var changed = false; var changed = false;
if ( µm.mustBlock(pageStats.pageHostname, reqHostname, 'cookie') ) { if ( µm.mustBlock(pageStore.pageHostname, reqHostname, 'cookie') ) {
changed = foilCookieHeaders(µm, details) || changed; changed = foilCookieHeaders(µm, details) || changed;
} }
// TODO: use cookie cell to determine whether the referrer info must be // TODO: use cookie cell to determine whether the referrer info must be
// foiled. // foiled.
if ( µm.userSettings.processReferer && µm.mustBlock(pageStats.pageHostname, reqHostname, '*') ) { if ( µm.userSettings.processReferer && µm.mustBlock(pageStore.pageHostname, reqHostname, '*') ) {
changed = foilRefererHeaders(µm, reqHostname, details) || changed; changed = foilRefererHeaders(µm, reqHostname, details) || changed;
} }
if ( µm.userSettings.spoofUserAgent ) { // TODO: move the master ua-spoofing switch into the matrix.
var mustSpoof = µm.userSettings.spoofUserAgent &&
µm.tMatrix.evaluateSwitchZ('ua-spoof-off', pageStore.pageHostname) === false;
if ( mustSpoof ) {
changed = foilUserAgent(µm, details) || changed; changed = foilUserAgent(µm, details) || changed;
// https://github.com/gorhill/httpswitchboard/issues/252 // https://github.com/gorhill/httpswitchboard/issues/252
// To avoid potential mismatch between the user agent from HTTP headers // To avoid potential mismatch between the user agent from HTTP headers
@ -617,7 +617,7 @@ var onHeadersReceived = function(details) {
// console.debug('onHeadersReceived()> "%s": %o', details.url, details); // console.debug('onHeadersReceived()> "%s": %o', details.url, details);
// Ignore schemes other than 'http...' // Ignore schemes other than 'http...'
if ( details.url.indexOf('http') !== 0 ) { if ( details.url.slice(0, 4) !== 'http' ) {
return; return;
} }
@ -710,25 +710,32 @@ var onMainDocHeadersReceived = function(details) {
} }
} }
// Evaluate // Maybe modify inbound headers
if ( µm.mustAllow(pageStats.pageHostname, requestHostname, 'script') ) { var csp = '';
// https://github.com/gorhill/httpswitchboard/issues/181
pageStats.pageScriptBlocked = false; // Enforce strict HTTPS?
return; if ( requestScheme === 'https' && µm.tMatrix.evaluateSwitchZ('https-strict', pageStats.pageHostname) ) {
csp += "default-src https: 'unsafe-inline' 'unsafe-eval'";
} }
// https://github.com/gorhill/httpswitchboard/issues/181 // https://github.com/gorhill/httpswitchboard/issues/181
pageStats.pageScriptBlocked = true; pageStats.pageScriptBlocked = µm.mustBlock(pageStats.pageHostname, requestHostname, 'script');
if ( pageStats.pageScriptBlocked ) {
// If javascript not allowed, say so through a `Content-Security-Policy` // If javascript not allowed, say so through a `Content-Security-Policy` directive.
// directive. // console.debug('onMainDocHeadersReceived()> PAGE CSP "%s": %o', details.url, details);
// console.debug('onMainDocHeadersReceived()> PAGE CSP "%s": %o', details.url, details); csp += " script-src 'none'";
headers.push({ }
'name': 'Content-Security-Policy',
'value': "script-src 'none'"
});
return { responseHeaders: headers }; // https://github.com/gorhill/httpswitchboard/issues/181
if ( csp !== '' ) {
// If javascript not allowed, say so through a `Content-Security-Policy` directive.
// console.debug('onMainDocHeadersReceived()> PAGE CSP "%s": %o', details.url, details);
headers.push({
'name': 'Content-Security-Policy',
'value': csp
});
return { responseHeaders: headers };
}
}; };
/******************************************************************************/ /******************************************************************************/

Loading…
Cancel
Save