如何配置Nginx的CSP响应标头?

Nginx

1 基础知识

1.1 CSP的简介

– CSP即英文Content Security Policy的简称,中文翻译为内容安全策列
– CSP是有一种安全标准,支持防止跨站点脚本(XSS)、点击劫持和其他代码注入攻击

1.2 CSP的作用


– CSP支持通过HTTP响应头的适当定义来控制Web应用程序允许加载那些资源
– CSP支持缓解和检测XSS攻击(利用浏览器对服务器内容的信任)
– CSP支持服务器管理员指定浏览器可以信任那些Internet域的执行脚本(允许白名单域,忽略其他域)

1.3 CSP头的范例

<meta
  http-equiv="Content-Security-Policy"
  content="default-src 'self'; img-src https://*; child-src 'none';" />

1.4 CSP的定义

1.4.1 CSP的语法

Content-Security-Policy: <policy-directive>; <policy-directive>

需要注意的是,
– 多个策略指令使用“;”号分隔
– 每个策略指令“ <policy-directive>”的基本格式为“<directive> <value>”
– 关键字“directive”代表策略指令的健,关键字“value”代表策略制定的值

1.4.2 CSP的健-Fetch directives

– 指令“Fetch directives”即获取指令,可控制某些可能被加载资源的位置
– 健“child-src”,声明允许加载Web Workers和“<frame>”、“<iframe>”定义的源
– 健“connect-src”声明允许加载的脚本接口URL源
– 健“default-src”声明“Fetch directive”备用加载源
– 健“font-src”声明允许加载“@font-fac”定义的字体源
– 健“frame-src”声明允许加载“<frame>”和“<iframe>”定义的源
– 健“img-src”声明允许加载图片和网站图标的源
– 健“manifest-src”声明允许加载应用程序的源
– 健“media-src”声明允许“<audio>”、“<video>”、“<track>”加载的媒体源
– 健“object-src”声明允许“<object>”、“<embed>”、“<applet>”加载的源
– 健“prefetch-src”声明允许预取或预呈现的源
– 健“script-src”声明允许加载JavaScript和WebAssembly源
– 健“script-src-elem”声明允许加载“<script>”的JavaScript源
– 健“script-src-attr”声明允许加载JavaScript内联时间处理程序的源
– 健“style-src”声明允许加载样式表的源
– 健“style-src-elem”声明允许加载“<style>”和“<link>”的源
– 健“style-src-attr”声明允许加载DOM元素的内联样式源
– 健“worker-src”声明允许加载Work、SharedWorker、ServiceWorker的源

1.4.3 CSP的健-Document directives

– 指令“Document directives”即文档指令用于定义文档或工作环境属性
– 健“base-uri”,声明允许“<base>”加载文档元素
– 健“sandbox”,声明为类似“<iframe>”的“sandbox”属性启动“sandbox”

1.4.4 CSP的健-Navigation directives

– 指令“Navigation directives”控制用户导航或提交表单的位置
– 健“form-action”,声明允许加载
– 健“frame-ancestors”,声明允许“<frame>”、“<iframe>”“<object>”“<embed>”“<applet>”加载的有效父级
– 健“navigate-to”,声明允许加载导航源的方式,例“<form>”,“<a>”、“window.location”、“window.open”

1.4.5 CSP的健-Reporting directives

– 指令“Reporting directives”控制CSP违规的报告过程
– 健“report-uri”,声明用户代理违反内容安全策列的动作(通过HTTP POST请求发送JSON文档到指定的URI)
– 健“report-to”,声明触发的SecurityPolicyViolationEvent

1.4.5 CSP的健-其他指令

– 健“require-trusted-types-for”,声明为DOM XSS注入接收器处强制执行信任类型
– 健“trusted-types”,声明指定信任类型(策列白名单)
– 健“upgrade-insecure-requests”,声明用户代理将站点不安全URL替换为安全的URL

1.4.6 CSP的值-Keyword values

– 值“none”,声明不允许加载任何资源
– 值“self”,声明只允许来自当前来源的资源
– 值“strict-dynamic”,声明动态的随机数或哈希而授权脚本
– 值“report-sample”,声明需要在违规报告中包含违规代理范例

1.4.7 CSP的值-Unsafe keyword values

– 值“unsafe-inline”,声明允许使用内联资源
– 值“unsafe-eval”,声明允许使用动态代码评估
– 值“unsafe-hashes”,声明允许启用特定内联时间处理程序
– 值“unsafe-allow-redirects”,声明待定

1.4.8 CSP的值-Hosts values

– 声明通配主机,如“example.com”、“*.example.com”或“https://*.example.com:12/path/to/file.js”
– 声明通配URI,如“example.com/api/”将匹配“example.com/api/users/new”
– 声明通配协议,“example.com/file.js”将匹配“https://example.com/file.js”或“http://example.com/file.js”
– 声明特定协议,例如“https:”、“http:”、“data:”

1.4.9 CSP的值-其他

– 值“nonce-*”,声明允许脚本加密随机数(仅使用一次)
– 值“sha*-*”,声明使用“sha256”、“sha384”或“sha512”

2 最佳实践

2.1 加入替换代码

vim /etc/nginx/conf.d/www.cmdschool.org.conf

加入如下配置,

server {
    #...
    add_header Content-Security-Policy "default-src 'self' *.cmdschool.org *.cmdschool.com" always;
    #add_header Content-Security-Policy "default-src *; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * data: 'unsafe-inline'; connect-src * 'unsafe-inline'; frame-src *;" always;
    #...
}

或者,你可以尝试如下方案,

server {
    #...
    proxy_hide_header Content-Security-Policy;
    add_header Content-Security-Policy "default-src 'self' https 'unsafe-inline' 'unsafe-eval'" always;
    #...
}

增加配置后,你需要重载服务使配置生效,

systemctl reload nginx.service

2.2 确认配置

curl -I https://www.cmdschool.org

可见如下显示,

#...
Content-Security-Policy: default-src 'self' *.cmdschool.org *.cmdschool.com
#...

参阅文档
=======================

CSP的介绍
——————-
https://www.imperva.com/learn/application-security/content-security-policy-csp-header/
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

CSP的定义
——————
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy

没有评论

发表回复

Nginx
如何使用Nginx发布维护公告?

1 前言 一个问题,一篇文章,一出故事。 最近由于需要发布维护公告,想着这种东西以后用得着,于是总结 …

Nginx
如何实现Nginx第一次访问跳转?

1 前言 一个问题,一篇文章,一出故事。 笔者在NextCloud生产环境中需要实现首次登录显示公告 …

Nginx
如何实现Nginx首次访问跳转?

1 前言 一个问题,一篇文章,一出故事。 笔者在NextCloud生产环境中需要实现首次登录显示公告 …