Skip to content
This repository was archived by the owner on Nov 15, 2017. It is now read-only.

Commit 32af1f6

Browse files
committed
this fixes #35
1 parent d3ae744 commit 32af1f6

File tree

8 files changed

+183
-90
lines changed

8 files changed

+183
-90
lines changed

background.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<script src="js/storage.js"></script>
2323
<script src="js/tab.js"></script>
2424
<script src="js/traffic.js"></script>
25-
<script src="js/utils.js"></script>
25+
<script src="js/contextmenu.js"></script>
2626
<script src="js/start.js"></script>
2727
</body>
2828
</html>

js/contextmenu.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*******************************************************************************
2+
3+
httpswitchboard - a Chromium browser extension to black/white list requests.
4+
Copyright (C) 2013 Raymond Hill
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see {http://www.gnu.org/licenses/}.
18+
19+
Home: https://github.com/gorhill/httpswitchboard
20+
*/
21+
22+
/******************************************************************************/
23+
24+
chrome.contextMenus.create({
25+
type: 'normal',
26+
id: 'gdt-group0',
27+
title: 'Temporarily whitelist ...',
28+
documentUrlPatterns: ['http://*/*', 'https://*/*']
29+
},
30+
function(){}
31+
);
32+
33+
chrome.contextMenus.create({
34+
type: 'normal',
35+
id: 'revertPermissions',
36+
title: 'Remove all temporary permissions',
37+
documentUrlPatterns: ['http://*/*', 'https://*/*']
38+
},
39+
function(){}
40+
);
41+
42+
function contextMenuClickHandler(info, tab) {
43+
// "If the click did not take place in a tab,
44+
// "this parameter will be missing"
45+
if ( !tab ) {
46+
return;
47+
}
48+
49+
var pageURL = uriTools.normalizeURI(tab.url);
50+
var pageDomain = uriTools.domainFromURI(pageURL);
51+
52+
if ( !pageDomain ) {
53+
return;
54+
}
55+
56+
switch ( info.menuItemId ) {
57+
case 'gdt-group0':
58+
HTTPSB.whitelistTemporarily(pageURL, '*', pageDomain);
59+
smartReloadTab(tab.id);
60+
break;
61+
62+
case 'revertPermissions':
63+
HTTPSB.revertPermissions();
64+
smartReloadTabs();
65+
break;
66+
}
67+
}
68+
69+
chrome.contextMenus.onClicked.addListener(contextMenuClickHandler);
70+
71+
/******************************************************************************/
72+
73+
function updateContextMenuHandler(tabs) {
74+
if ( !tabs.length ) {
75+
return;
76+
}
77+
var tab = tabs[0];
78+
if ( !tab.url || !tab.url.length ) {
79+
return;
80+
}
81+
var pageUrl = uriTools.normalizeURI(tab.url);
82+
var pageDomain = uriTools.domainFromURI(pageUrl);
83+
var color = HTTPSB.evaluate(pageUrl, '*', pageDomain);
84+
chrome.contextMenus.update('gdt-group0', {
85+
title: 'Temporarily whitelist *.' + pageDomain,
86+
enabled: color.charAt(0) !== 'g' && !HTTPSB.off
87+
});
88+
chrome.contextMenus.update('revertPermissions', {
89+
enabled: !HTTPSB.off
90+
});
91+
}
92+
93+
function updateContextMenu() {
94+
chrome.tabs.query({ active: true }, updateContextMenuHandler);
95+
}
96+

js/inject.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ if ( window.location.href.match(/^https?:\/\//) ) {
2929
// This must be last, so that result is returned to extension.
3030
// This is used so that inline script tags and preemptively blocked scripts
3131
// (which won't generate web requests) are logged in the stats.
32-
// TODO: Do same with <object>, <embed>, they are currently underreported
33-
// when preemptively blocked.
3432
(function() {
3533
var r = {
3634
pageUrl: window.location.href,

js/start.js

Lines changed: 14 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ chrome.contentSettings.plugins.clear({});
3535
// For privacy reasons, ensure all exceptions are removed from settings.
3636
chrome.contentSettings.javascript.clear({});
3737

38+
// rhill 2013-12-05: now we allow all by default, and insert a
39+
// `Content-Policy-Directive` header to disable inline javascript.
40+
// External javascript will still be blocked the old way, by preventing the
41+
// resource from being fetched.
42+
// https://github.com/gorhill/httpswitchboard/issues/35
43+
chrome.contentSettings.javascript.set({
44+
primaryPattern: '*://*/*',
45+
setting: 'allow'
46+
});
47+
3848
/******************************************************************************/
3949

4050
function injectedCodeCallback(r) {
@@ -166,7 +176,10 @@ function onBeforeNavigateCallback(details) {
166176
return;
167177
}
168178
var hostname = uriTools.hostnameFromURI(details.url);
169-
setJavascript(hostname, HTTPSB.whitelisted(details.url, 'script', hostname));
179+
180+
// No longer needed, but I will just comment out for now.
181+
// https://github.com/gorhill/httpswitchboard/issues/35
182+
// setJavascript(hostname, HTTPSB.whitelisted(details.url, 'script', hostname));
170183
}
171184

172185
chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigateCallback);
@@ -227,78 +240,3 @@ function onDisconnectHandler() {
227240

228241
chrome.extension.onConnect.addListener(onConnectHandler);
229242

230-
/******************************************************************************/
231-
232-
chrome.contextMenus.create({
233-
type: 'normal',
234-
id: 'gdt-group0',
235-
title: 'Temporarily whitelist ...',
236-
documentUrlPatterns: ['http://*/*', 'https://*/*']
237-
},
238-
function(){}
239-
);
240-
241-
chrome.contextMenus.create({
242-
type: 'normal',
243-
id: 'revertPermissions',
244-
title: 'Remove all temporary permissions',
245-
documentUrlPatterns: ['http://*/*', 'https://*/*']
246-
},
247-
function(){}
248-
);
249-
250-
function contextMenuClickHandler(info, tab) {
251-
// "If the click did not take place in a tab,
252-
// "this parameter will be missing"
253-
if ( !tab ) {
254-
return;
255-
}
256-
257-
var pageURL = uriTools.normalizeURI(tab.url);
258-
var pageDomain = uriTools.domainFromURI(pageURL);
259-
260-
if ( !pageDomain ) {
261-
return;
262-
}
263-
264-
switch ( info.menuItemId ) {
265-
case 'gdt-group0':
266-
HTTPSB.whitelistTemporarily(pageURL, '*', pageDomain);
267-
smartReloadTab(tab.id);
268-
break;
269-
270-
case 'revertPermissions':
271-
HTTPSB.revertPermissions();
272-
smartReloadTabs();
273-
break;
274-
}
275-
}
276-
277-
chrome.contextMenus.onClicked.addListener(contextMenuClickHandler);
278-
279-
/******************************************************************************/
280-
281-
function updateContextMenuHandler(tabs) {
282-
if ( !tabs.length ) {
283-
return;
284-
}
285-
var tab = tabs[0];
286-
if ( !tab.url || !tab.url.length ) {
287-
return;
288-
}
289-
var pageUrl = uriTools.normalizeURI(tab.url);
290-
var pageDomain = uriTools.domainFromURI(pageUrl);
291-
var color = HTTPSB.evaluate(pageUrl, '*', pageDomain);
292-
chrome.contextMenus.update('gdt-group0', {
293-
title: 'Temporarily whitelist *.' + pageDomain,
294-
enabled: color.charAt(0) !== 'g' && !HTTPSB.off
295-
});
296-
chrome.contextMenus.update('revertPermissions', {
297-
enabled: !HTTPSB.off
298-
});
299-
}
300-
301-
function updateContextMenu() {
302-
chrome.tabs.query({ active: true }, updateContextMenuHandler);
303-
}
304-

js/tab.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -510,8 +510,8 @@ function createPageStats(pageUrl) {
510510

511511
// Create an entry for the tab if it doesn't exist
512512

513-
function bindTabToPageStats(tabId, pageUrl) {
514-
var pageStats = createPageStats(pageUrl);
513+
function bindTabToPageStats(tabId, pageURL) {
514+
var pageStats = createPageStats(pageURL);
515515
if ( !pageStats ) {
516516
return undefined;
517517
}
@@ -522,8 +522,8 @@ function bindTabToPageStats(tabId, pageUrl) {
522522
// https://github.com/gorhill/httpswitchboard/issues/67
523523
if ( tabId !== HTTPSB.behindTheSceneTabId ) {
524524
unbindTabFromPageStats(tabId);
525-
HTTPSB.pageUrlToTabId[pageUrl] = tabId;
526-
HTTPSB.tabIdToPageUrl[tabId] = pageUrl;
525+
HTTPSB.pageUrlToTabId[pageURL] = tabId;
526+
HTTPSB.tabIdToPageUrl[tabId] = pageURL;
527527
}
528528

529529
return pageStats;
@@ -609,8 +609,10 @@ function smartReloadTab(tabId) {
609609
if ( getStateHash(newState) != getStateHash(pageStats.state) ) {
610610
// Appears to help.
611611
// https://github.com/gorhill/httpswitchboard/issues/35
612-
var hostname = uriTools.hostnameFromURI(pageUrl);
613-
setJavascript(hostname, HTTPSB.whitelisted(pageUrl, 'script', hostname));
612+
// No longer needed, but I will just comment out for now.
613+
// https://github.com/gorhill/httpswitchboard/issues/35
614+
// var hostname = uriTools.hostnameFromURI(pageUrl);
615+
// setJavascript(hostname, HTTPSB.whitelisted(pageUrl, 'script', hostname));
614616
// console.debug('reloaded content of tab id %d', tabId);
615617
// console.debug('old="%s"\nnew="%s"', getStateHash(pageStats.state), getStateHash(newState));
616618
pageStats.state = newState;

js/traffic.js

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,13 +180,14 @@ function beforeRequestHandler(details) {
180180
}
181181
}
182182

183-
// quickProfiler.stop('beforeRequestHandler | evaluate&record');
184-
185183
// If it is a frame and scripts are blacklisted for the
186184
// hostname, disable scripts for this hostname, necessary since inline
187185
// script tags are not passed through web request handler.
188186
if ( isMainFrame ) {
189-
setJavascript(hostname, httpsb.whitelisted(pageURL, 'script', hostname));
187+
// No longer needed, but I will just comment out for now.
188+
// https://github.com/gorhill/httpswitchboard/issues/35
189+
// setJavascript(hostname, httpsb.whitelisted(pageURL, 'script', hostname));
190+
190191
// when the tab is updated, we will check if page has at least one
191192
// script tag, this takes care of inline scripting, which doesn't
192193
// generate 'script' type web requests.
@@ -195,6 +196,8 @@ function beforeRequestHandler(details) {
195196
// Collect global stats
196197
httpsb.requestStats.record(type, block);
197198

199+
// quickProfiler.stop('beforeRequestHandler | evaluate&record');
200+
198201
// whitelisted?
199202
if ( !block ) {
200203
// console.debug('beforeRequestHandler > allowing %s from %s', type, hostname);
@@ -281,6 +284,50 @@ function beforeSendHeadersHandler(details) {
281284

282285
/******************************************************************************/
283286

287+
// To prevent inline javascript from being executed.
288+
289+
// Prevent inline scripting using `Content-Security-Policy`:
290+
// https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html
291+
292+
// This fixes:
293+
// https://github.com/gorhill/httpswitchboard/issues/35
294+
295+
function headersReceivedHandler(details) {
296+
297+
// Ignore anything which is not top frame
298+
var type = details.type;
299+
if ( type !== 'main_frame' && type !== 'sub_frame' ) {
300+
return;
301+
}
302+
303+
// Ignore traffic outside tabs
304+
var tabId = details.tabId;
305+
if ( tabId < 0 ) {
306+
return;
307+
}
308+
309+
var pageStats = pageStatsFromTabId(tabId);
310+
// Can happen I suppose...
311+
if ( !pageStats ) {
312+
return;
313+
}
314+
315+
// Evaluate according to scope
316+
var pageURL = pageUrlFromPageStats(pageStats);
317+
var hostname = uriTools.hostnameFromURI(details.url);
318+
var noScript = HTTPSB.blacklisted(pageURL, 'script', hostname);
319+
if ( !noScript ) {
320+
return;
321+
}
322+
323+
// If javascript not allowed, say so through a `Content-Security-Policy`
324+
// directive.
325+
details.responseHeaders.push({ 'name': 'Content-Security-Policy', 'value': "script-src 'none'" });
326+
return { responseHeaders: details.responseHeaders };
327+
}
328+
329+
/******************************************************************************/
330+
284331
var webRequestHandlerRequirements = {
285332
'tabsBound': 0,
286333
'listsLoaded': 0
@@ -328,4 +375,15 @@ function startWebRequestHandler(from) {
328375
},
329376
['blocking', 'requestHeaders']
330377
);
378+
379+
chrome.webRequest.onHeadersReceived.addListener(
380+
headersReceivedHandler,
381+
{
382+
'urls': [
383+
"http://*/*",
384+
"https://*/*"
385+
]
386+
},
387+
['blocking', 'responseHeaders']
388+
);
331389
}

js/utils.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
// Enable/disable javascript for a specific hostname.
2525

26+
/*
2627
function setJavascriptCallback(windows, hostname, setting) {
2728
// Need to do this to avoid "You cannot set a preference with scope
2829
// 'incognito_session_only' when no incognito window is open."
@@ -54,4 +55,4 @@ function setJavascript(hostname, state) {
5455
setJavascriptCallback(windows, hostname, setting);
5556
});
5657
}
57-
58+
*/

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 2,
33
"name": "__MSG_extName__",
4-
"version": "0.6.3",
4+
"version": "0.6.4",
55
"description": "__MSG_extShortDesc__",
66
"icons": {
77
"16": "icon_16.png",

0 commit comments

Comments
 (0)