I am a little confused with the directives available with Content Security Policy Header. Mainly confused with connect-src
, script-src
and style-src
I have a javascript, which sends Fetch
, Ajax
(on the same domain) and dynamically loads a link tag that has a stylesheet.
If I have to get my script whitelisted on a domain, should this be part of all connect-src
, script-src
and style-src
? I am a little confused here.
To make it clearer, there is a script at https://example.com
which loads, sends data from https://example.com
and loads stylesheet sitting at https://some-another-domain.com
. How should the content security policy reflect this? Should connect-src
, script-src
and style-src
include both the domains?
Could someone help clarify this?
Each directive should contain only sources which it covers (controls).
connect-src
directive covers the URLs from which resources can be loaded using following script API interfaces(see the test):<a ping='...'>
fetch()
XMLHttpRequest()
sendBeacon()
WebSocket()
(hence ws:
/wss:
scheme can be specified in connect-src
/default-src
only)EventSource()
Therefore if you perform XMLHttpRequest('https://example.com/ajax')
or use jQuery $ajax('https://example.com/ajax')
which internally calls XMLHttpRequest(), you need to allow the https://example.com
in the connect-src
:
connect-src https://example.com;
Similarly if you use fetch('https://google.com/api/json')
, you need to add this host-source to the connect-src
:
connect-src https://example.com https://google.com/api/;
and so on for all 6 the APIs above.
script-src
directive controls 5 things:<script src='http://example.com/script.js'></script>
. You need to allow relevant host-sources in the script-src
for that. Alternatively 'nonce-value'
/'hash-value'
token can be used.<script>...</script>
. You need to use 'unsafe-inline'
or 'nonce-value'/'hash-value' tokens in the script-src
to allow such scripts.eval()
, setTimeout()
, setInterval()
, Function()
, setImmediate()
, execScript()
funct calls are gated on the 'unsafe-eval'
source expression. If you use those you need to have 'unsafe-eval'
in the script-src
(with some exceptions for setTimeout()
/setInterval()
).<a href='javascript:...'>
.<div onblur='...'>
, <input onclick='...'>
. *
for last 2 things you need to have 'unsafe-inline' in the script-src
directive or use unsafe-hashes
+ 'hash-value'
tokens paired (supported with some bugs as for now).<link href='http://example.com/min/css.css' rel='stylesheet'>
. In this case you need to add http://example.com
host-source to the style-src
directive.@import url('https://example.com/style_import.css')
Link: https://example.com/file.css; rel=stylesheet
.<style>...</style>
. You need to have 'unsafe-inline'
or 'nonce-value'
/'hash-value'
in the style-src
to allow these.<tag style='color:green; margin:0 auto;'>
. You need to have 'unsafe-inline'
in the style-src
to allow these. Or use paired the 'unsafe-hashes'
+ 'hash-value'
(is not widely supported as for now). *
JS call setAttribute('style', 'display:none;')
is considered as <tag style='display:none;'>
above.CSSStyleSheet.insertRule()
, CSSGroupingRule.insertRule()
, CSSStyleDeclaration.cssText
and CSSStyleRule.selectorText
was intended to be gated to 'unsafe-eval'
in the style-src
, but it's not implemented yet.Any usage of the above constructs (even via script calls) requires to allow relevant sources or tokens in the styler-src
directive.