乐趣区

关于nginx:网络CSP和Nonce

白名单

浏览器无奈辨别 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?
退出移动版