Replace ad script blacklist with whitelist.

This commit is contained in:
ccd0 2016-06-02 02:57:55 -07:00
parent 59bac43afb
commit 10d761bcbe
5 changed files with 57 additions and 19 deletions

View File

@ -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'

View File

@ -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>

View File

@ -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'

View File

@ -16,21 +16,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
@ -64,11 +49,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.

View File

@ -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()