Replace ad script blacklist with whitelist.
This commit is contained in:
parent
903289d324
commit
416a31b3e6
@ -436,7 +436,7 @@ Settings =
|
||||
$.id('lastarchivecheck').textContent = 'never'
|
||||
|
||||
items = {}
|
||||
for name in ['archiveLists', 'archiveAutoUpdate', 'captchaLanguage', 'boardnav', 'time', 'backlink', 'fileInfo', 'QR.personas', 'favicon', 'usercss', 'customCooldown']
|
||||
for name in ['archiveLists', 'archiveAutoUpdate', 'captchaLanguage', 'boardnav', 'time', 'backlink', 'fileInfo', 'QR.personas', 'favicon', 'usercss', 'customCooldown', 'jsWhitelist']
|
||||
items[name] = Conf[name]
|
||||
input = inputs[name]
|
||||
event = if name in ['archiveLists', 'archiveAutoUpdate', 'QR.personas', 'favicon', 'usercss'] then 'change' else 'input'
|
||||
|
||||
@ -140,3 +140,9 @@
|
||||
<button id="apply-css">Apply CSS</button>
|
||||
<textarea name="usercss" class="field" spellcheck="false"></textarea>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Javascript Whitelist</legend>
|
||||
<div>Sources from which Javascript is allowed to be loaded by <a href="http://content-security-policy.com/#source_list" target="_blank">Content Security Policy</a>.</div>
|
||||
<textarea name="jsWhitelist" class="field" spellcheck="false"></textarea>
|
||||
</fieldset>
|
||||
|
||||
@ -792,6 +792,16 @@ Config =
|
||||
"""
|
||||
sjisPreview: false
|
||||
|
||||
jsWhitelist: '''
|
||||
http://s.4cdn.org
|
||||
https://s.4cdn.org
|
||||
http://www.google.com
|
||||
https://www.google.com
|
||||
https://www.gstatic.com
|
||||
'unsafe-inline'
|
||||
'unsafe-eval'
|
||||
'''
|
||||
|
||||
captchaLanguage: ''
|
||||
|
||||
time: '%m/%d/%y(%a)%H:%M:%S'
|
||||
|
||||
@ -13,21 +13,6 @@ Main =
|
||||
$.ready -> Captcha.fixes.init()
|
||||
return
|
||||
|
||||
# Disrupt loading of ads from malicious/irresponsible providers.
|
||||
$.global ->
|
||||
nuke = (obj, prop) ->
|
||||
try
|
||||
Object.defineProperty obj, prop,
|
||||
configurable: false
|
||||
get: -> throw new Error()
|
||||
set: -> throw new Error()
|
||||
for prop in ['atOptions', 'adsterra_key', 'EpmadsConfig', 'epmads_key', 'EpomConfig', 'epom_key', 'exoDocumentProtocol', 'supp_key']
|
||||
nuke window, prop
|
||||
return
|
||||
$.on window, 'beforescriptexecute', (e) ->
|
||||
host = e.target.src.split('/')[2]?.match(/[^.]+\.[^.]+$/)?[0]
|
||||
e.preventDefault() if host in ['bnhtml.com', 'ecpmrocks.com', 'advertisation.com', 'exoclick.com', 'n298adserv.com']
|
||||
|
||||
# Detect multiple copies of 4chan X
|
||||
$.on d, '4chanXInitFinished', ->
|
||||
if Main.expectInitFinished
|
||||
@ -61,11 +46,35 @@ Main =
|
||||
Conf['JSON Navigation'] = true
|
||||
Conf['Oekaki Links'] = true
|
||||
|
||||
# Pseudo-enforce default whitelist while configuration loads
|
||||
$.global ->
|
||||
{whitelist} = document.currentScript.dataset
|
||||
whitelist = whitelist.split('\n').filter (x) -> x[0] isnt "'"
|
||||
oldFun = {}
|
||||
for key in ['createElement', 'write']
|
||||
oldFun[key] = document[key]
|
||||
document[key] = do (key) -> (arg) ->
|
||||
s = document.currentScript
|
||||
if s and s.src and whitelist.indexOf(s.src.split('/')[..2].join('/')) < 0
|
||||
throw Error()
|
||||
oldFun[key].call document, arg
|
||||
document.addEventListener 'csp-ready', ->
|
||||
document[key] = oldFun[key] for key of oldFun
|
||||
, false
|
||||
,
|
||||
whitelist: Conf['jsWhitelist']
|
||||
|
||||
# Get saved values as items
|
||||
items = {}
|
||||
items[key] = undefined for key of Conf
|
||||
items['previousversion'] = undefined
|
||||
$.get items, (items) ->
|
||||
|
||||
# Enforce JS whitelist
|
||||
jsWhitelist = items['jsWhitelist'] ? Conf['jsWhitelist']
|
||||
$.addCSP "script-src #{jsWhitelist.replace(/[\s;]+/g, ' ')}"
|
||||
$.event 'csp-ready'
|
||||
|
||||
$.asap docSet, ->
|
||||
|
||||
# Don't hide the local storage warning behind a settings panel.
|
||||
|
||||
@ -138,6 +138,18 @@ $.addStyle = (css, id, test='head') ->
|
||||
$.add d.head, style
|
||||
style
|
||||
|
||||
$.addCSP = (policy) ->
|
||||
meta = $.el 'meta',
|
||||
httpEquiv: 'Content-Security-Policy'
|
||||
content: policy
|
||||
if d.head
|
||||
$.add d.head, meta
|
||||
$.rm meta
|
||||
else
|
||||
head = $.add (doc or d), $.el('head')
|
||||
$.add head, meta
|
||||
$.rm head
|
||||
|
||||
$.x = (path, root) ->
|
||||
root or= d.body
|
||||
# XPathResult.ANY_UNORDERED_NODE_TYPE === 8
|
||||
@ -296,15 +308,16 @@ $.queueTask = do ->
|
||||
taskQueue.push arguments
|
||||
setTimeout execTask, 0
|
||||
|
||||
$.globalEval = (code) ->
|
||||
$.globalEval = (code, data) ->
|
||||
script = $.el 'script',
|
||||
textContent: code
|
||||
$.extend script.dataset, data if data
|
||||
$.add (d.head or doc), script
|
||||
$.rm script
|
||||
|
||||
$.global = (fn) ->
|
||||
$.global = (fn, data) ->
|
||||
if doc
|
||||
$.globalEval "(#{fn})();"
|
||||
$.globalEval "(#{fn})();", data
|
||||
else
|
||||
# XXX dwb
|
||||
fn()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user