白名单
浏览器无奈辨别JS的起源,有的JS是来自利用自身的,而有的则有可能来自歹意注入。因为浏览器无奈辨别JS的起源,这可能会被XSS攻打所利用。
什么是XSS?
例如在一个博客网站,发表一篇蕴含歹意脚本的<script>
标签的文章,这篇文章会保留在服务器中。当其他人拜访这篇文章时,会在访问者的浏览器中执行歹意的脚本。因为浏览器无奈辨别JS代码是好的,还是坏的。浏览器都会下载并执行JS。
CSP(Content-Security-Policy)
Content-Security-Policy 的 HTTP Header 能够批示浏览器只信赖指定白名单的JS源。即便通过XSS攻打注入了歹意的脚本文件,浏览器也不会执行。
CSP Nginx 示例
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;
}
}
增加CSP之前
jqeury的cdn能够失常被加载
增加CSP之后
增加CSP后,浏览器只会抛出一个谬误,不会执行任何白名单之外的JS代码
其余资源
除了javascript外,CSP还能够对网站的其余的资源进行限度
- style-src 限度css的资源地址
- img-src 限度图片的资源地址
- font-src 限度字体资源的地址
- …… 等等
# 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……)的资源作出限度,那么就代表不限度资源的起源。默认能够加载任何起源的资源。
应用 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'";
}
http-equiv
除了通过配置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';";
}
nonce
如果你放心内联脚本的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';";
}
参考
- HTML <meta> http-equiv Attribute
- 内容平安政策
- nginx Content-Security-Policy Headers
- What’s the purpose of the HTML “nonce” attribute for script and style elements?
发表回复