为 ASP.NET Core 强制实施内容安全策略 BlazorEnforce a Content Security Policy for ASP.NET Core Blazor
本文内容
作者: Javier Calvarro 使用和Luke Latham
重要
Blazor WebAssembly 为预览版状态
ASP.NET Core 3.0 支持 Blazor Server。Blazor WebAssembly 在 ASP.NET Core 3.1 中为预览版。
跨站点脚本(XSS)是一个安全漏洞,攻击者将一个或多个恶意客户端脚本放入应用程序的呈现内容中。内容安全策略(CSP)通过通知浏览器的有效情况来帮助防范 XSS 攻击:
- 已加载内容的源,包括脚本、样式表和图像。
- 页执行的操作,指定窗体的允许的 URL 目标。
- 可以加载的插件。
若要将 CSP 应用到应用,开发人员需要在一个或多个 Content-Security-Policy
标头或 <meta>
标记中指定若干 CSP 内容安全指令。
加载页面时,浏览器会对策略进行评估。浏览器将检查页的源并确定它们是否满足内容安全指令的要求。如果资源不满足策略指令,浏览器不会加载资源。例如,请考虑不允许第三方脚本的策略。当某个页面包含 src
属性中具有第三方来源的 <script>
标记时,浏览器将阻止加载该脚本。
大多数新式桌面和移动浏览器(包括 Chrome、Edge、Firefox、Opera 和 Safari)都支持 CSP。建议将 CSP 用于 Blazor 应用。
策略指令Policy directives
最少指定 Blazor 应用的以下指令和源。根据需要添加其他指令和源。以下指令用于本文的应用策略部分,其中提供了 Blazor WebAssembly 和 Blazor 服务器的示例安全策略:
- 基础 uri – 限制页的
<base>
标记的 url。指定self
,以指示应用程序的源(包括方案和端口号)是有效的源。 - 阻止所有混合内容– 阻止加载混合 HTTP 和 HTTPS 内容。
- 默认-src – 指示策略未显式指定的源指令的回退。指定
self
,以指示应用程序的源(包括方案和端口号)是有效的源。 - img-src – 指示映像的有效源。
- 指定
data:
允许从data:
Url 加载图像。 - 指定
https:
允许从 HTTPS 终结点加载图像。
- 指定
- 对象-src – 指示
<object>
、<embed>
和<applet>
标记的有效源。指定none
以阻止所有 URL 源。 - 脚本-src – 表示脚本的有效源。
- 指定用于启动脚本的
https://stackpath.bootstrapcdn.com/
主机源。 - 指定
self
,以指示应用程序的源(包括方案和端口号)是有效的源。 - 在 Blazor WebAssembly 应用中:
- 指定下列哈希,以允许所需的 Blazor WebAssembly 内联脚本加载:
sha256-v8ZC9OgMhcnEQ/Me77/R9TlJfzOBqrMTW8e1KuqLaqc=
sha256-If//FtbPc03afjLezvWHnC3Nbu4fDM04IIzkPaf3pH0=
sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=
- 指定
unsafe-eval
,以使用从字符串创建代码eval()
和方法。
- 指定下列哈希,以允许所需的 Blazor WebAssembly 内联脚本加载:
- 在 Blazor Server 应用程序中,为内联脚本指定为样式表执行回退检测的
sha256-34WLX60Tw3aG6hylk0plKbZZFXCuepeQ6Hu7OqRf8PI=
哈希。
- 指定用于启动脚本的
- 样式-src – 指示样式表的有效源。
- 为启动样式表指定
https://stackpath.bootstrapcdn.com/
主机源。 - 指定
self
,以指示应用程序的源(包括方案和端口号)是有效的源。 - 指定
unsafe-inline
允许使用内联样式。Blazor Server apps 中的 UI 需要内联声明,以便在初始请求后重新连接客户端和服务器。在将来的版本中,可能会删除内联样式,以便不再需要unsafe-inline
。
- 为启动样式表指定
- 升级-不安全-请求– 表明应通过 HTTPS 安全地获取来自不安全(HTTP)源的内容 url。
除 Microsoft Internet Explorer 外,所有浏览器都支持前面的指令。
获取更多内联脚本的 SHA 哈希:
- 应用 "应用策略" 部分中所示的 CSP。
- 在本地运行应用程序时,访问浏览器的 "开发人员工具" 控制台。当存在 CSP 标头或
meta
标记时,浏览器将为被阻止的脚本计算并显示哈希。 - 将浏览器提供的哈希复制到
script-src
源。在每个哈希两边使用单引号。
有关内容安全策略级别2浏览器支持矩阵,请参阅可以使用:内容安全策略级别 2。
应用策略Apply the policy
使用 <meta>
标记来应用策略:
- 将
http-equiv
属性的值设置为Content-Security-Policy
。 - 将指令放在
content
特性值中。用分号分隔指令(;
)。 - 始终将
meta
标记放在<head>
内容中。
以下部分介绍 Blazor WebAssembly 和 Blazor 服务器的示例策略。对于每个版本的 Blazor,本文都对这些示例进行了版本控制。若要使用适合你版本的版本,请在此网页上选择包含版本下拉选择器的文档版本。
Blazor WebAssembly WebAssembly
在wwwroot/index.html主机页的 <head>
内容中,应用策略指令部分中描述的指令:
<meta http-equiv="Content-Security-Policy"
content="base-uri 'self';
block-all-mixed-content;
default-src 'self';
img-src data: https:;
object-src 'none';
script-src https://stackpath.bootstrapcdn.com/
'self'
'sha256-v8ZC9OgMhcnEQ/Me77/R9TlJfzOBqrMTW8e1KuqLaqc='
'sha256-If//FtbPc03afjLezvWHnC3Nbu4fDM04IIzkPaf3pH0='
'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA='
'unsafe-eval';
style-src https://stackpath.bootstrapcdn.com/
'self'
'unsafe-inline';
upgrade-insecure-requests;">
Blazor 服务器 Server
在 "页面/_Host的 <head>
内容" 主机页上,应用策略指令部分中描述的指令:
<meta http-equiv="Content-Security-Policy"
content="base-uri 'self';
block-all-mixed-content;
default-src 'self';
img-src data: https:;
object-src 'none';
script-src https://stackpath.bootstrapcdn.com/
'self'
'sha256-34WLX60Tw3aG6hylk0plKbZZFXCuepeQ6Hu7OqRf8PI=';
style-src https://stackpath.bootstrapcdn.com/
'self'
'unsafe-inline';
upgrade-insecure-requests;">
元标记限制Meta tag limitations
<meta>
标记策略不支持以下指令:
若要支持前面的指令,请使用名为 Content-Security-Policy
的标头。指令字符串是标头的值。
测试策略并接收冲突报告Test a policy and receive violation reports
测试有助于确认在生成初始策略时不会无意中阻止第三方脚本。
若要在不强制实施策略指令的情况下测试策略,请将基于标头的策略 <meta>
标记的 http-equiv
属性或标头名称设置为 "Content-Security-Policy-Report-Only
"。故障报告作为 JSON 文档发送到指定的 URL。有关详细信息,请参阅MDN web 文档:仅限内容安全策略。
若要在策略处于活动状态时报告冲突,请参阅以下文章:
尽管不再建议使用 report-uri
,但在所有主要浏览器都支持 report-to
之前,都应使用这两个指令。不要专门使用 report-uri
,因为对 report-uri
的支持可能会随时从浏览器中删除。完全支持 report-to
时,删除对策略中 report-uri
的支持。若要跟踪 report-to
的采用,请参阅可以使用:报告到。
每次发布时测试和更新应用的策略。
疑难解答Troubleshoot
- 浏览器的 "开发人员工具" 控制台中会出现错误。浏览器提供以下信息:
- 不符合策略的元素。
- 如何修改策略以允许阻止的项目。
- 仅当客户端的浏览器支持所有包含的指令时,策略才会完全有效。有关当前的浏览器支持矩阵,请参阅可以使用:内容安全策略。