浏览器没法区分JS的来源,有的JS是来自应用自己的,而有的则有可能来自恶意注入。因为浏览器没法区分JS的来源,这可能会被XSS攻击所利用。javascript
例如在一个博客网站,发表一篇包含恶意脚本的<script>
标签的文章,这篇文章会保存在服务器中。当其余人访问这篇文章时,会在访问者的浏览器中执行恶意的脚本。由于浏览器没法区分JS代码是好的,仍是坏的。浏览器都会下载并执行JS。css
Content-Security-Policy 的 HTTP Header 能够指示浏览器只信任指定白名单的JS源。即便经过XSS攻击注入了恶意的脚本文件,浏览器也不会执行。html
server { listen 8090; server_name localhost; root /Users/zhangyue/Desktop/csp; index index.html; add_header Content-Security-Policy "script-src 'self';"; location ~* \.(?:js|css)$ { expires 7d; add_header Cache-Control no-store; } }
jqeury的cdn能够正常被加载java
添加CSP后,浏览器只会抛出一个错误,不会执行任何白名单以外的JS代码nginx
除了javascript外,CSP还能够对网站的其余的资源进行限制web
# img-src 为图片资源增长白名单 server { add_header Content-Security-Policy "script-src 'self';"; # 只容许http://photocdn.sohu.com; 和 当面域名下的图片进行加载 add_header Content-Security-Policy "img-src 'self' http://photocdn.sohu.com;"; }
可是值得注意的是,若是你不在nginx中对具体(css,js,image……)的资源做出限制,那么就表明不限制资源的来源。默承认以加载任何来源的资源。shell
使用 default-src 能够为没有指定白名单的资源,提供一个默认的白名单。浏览器
server { listen 8090; server_name localhost; index index.html; # default-src 为没有提供的资源提供了白名单: 'self',只容许加载当前域名下的资源 add_header Content-Security-Policy "script-src 'self';img-src 'self' http://photocdn.sohu.com;default-src 'self'"; }
除了经过配置Nginx,为页面添加CSP。还能够经过 meta 标签的http-equiv的属性,添加页面添加CSP。http-equiv能够为content属性值提供,提供http头。安全
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 添加CSP --> <meta http-equiv="Content-Security-Policy" content="script-src 'self';img-src 'self' http://photocdn.sohu.com;default-src 'self'"> <title>Document</title> </head> <body> </body> </html>
设置CSP,默认是静止内联JS代码执行的。若是必定要执行内联的JS代码,能够将 script-src 设置为 'unsafe-inline' ,以容许内联JS的执行。服务器
server { listen 8090; server_name localhost; index index.html; # 容许内联js和本域名下的js执行 add_header Content-Security-Policy "script-src 'self' 'unsafe-inline';"; }
若是你担忧内联脚本的JS注入,可是又须要内联JS的执行。可使用nonce属性。CSP Header会返回一个随机字符串,当它与script标签的nonce属性相匹配时,说明这段内联的js是安全的,是能够执行的。
可是这个随机字符串,应当是惟一,不该该是写死的。下面的例子,只是为了说明。若是是固定的nonce值,那么nonce没有任何意义,由于攻击者能够将本身注入的script标签也添加上相同的nonce值。
server { listen 8090; server_name localhost; index index.html; # 一个随机的字符串 add_header Content-Security-Policy "script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa' 'self';"; }