65.9K
CodeProject 正在变化。 阅读更多。
Home

Web 开发人员需要了解的内容安全策略 (CSP)

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2019年4月12日

CPOL

7分钟阅读

viewsIcon

11472

downloadIcon

86

本文讨论了 Web 开发人员需要了解的内容安全策略。

引言

内容安全策略 (CSP) 是万维网联盟 (W3C) 推出的一项计算机安全标准,用于防止跨站脚本 (XSS) 和点击劫持攻击。简单来说,CSP 是一个允许在网页上加载或执行的内容来源的白名单。我们将探讨 CSP 的三个版本以及每个版本的相关功能,但需要注意的是,CSP Level 3 尚未被批准为 W3C 推荐标准,目前仍是正在进行的草案。在标准化之前,它仍可能随时发生变化。在接下来的内容中,我们会指出这些版本之间的区别。

什么是跨站脚本?

跨站脚本 (XSS) 攻击是一种代码注入类型,其中恶意脚本被注入到受信任的网站中。一个很好的例子可能发生在电子商务网站上:一个买家发布了一个带有恶意代码的产品评论,该代码被保存在服务器上。对于每个查看该产品评论的客户,都会执行恶意代码。

CSP 的实际应用

CSP 可以在 HTTP 响应头中指定。当 Web 客户端(如 Web 浏览器)从 Web 服务器请求资源时,它会发送一个 HTTP 请求,并在请求头中包含服务器的许多信息。如果请求成功,Web 服务器会回复该资源,并在响应头中告知 Web 浏览器如何处理响应。在 CSP 的情况下,它指定了从哪里获取网页内容的受信任来源。在支持 CSP 2 的浏览器中,我们还可以选择在 HTML meta 标签中指定 CSP。在我们的示例中,我们将使用这种方式;我们采取一种与 Web 框架无关的方法来保持简单。您只需要一个文本编辑器和现代 Web 浏览器即可遵循这些示例。

CSP 的结构

CSP 以 `Content-Security-Policy` 文本开头,后面跟着一个或多个指令。每个指令以分号结束,分号可以作为下一个指令的开始。每个指令可以有零个或多个值。值之间用空格分隔。通常,值只是一个受信任的来源 URI。

Content-Security-Policy [directive] <value>;

这是一个单指令 CSP 的示例。`default-src` 指令和 '`self`' 值指示 Web 浏览器仅信任来自与网页相同来源的内容。

Content-Security-Policy default-src 'self';

下面显示了 `meta` 标签中等效的 CSP。

<meta http-equiv="Content-Security-Policy" content="default-src 'self';>

请注意,`meta` 标签必须在 HTML 的 `head` 部分指定,而不是在 `body` 部分。开发人员必须注意的一个大缺点是:使用 `meta` 标签方法时,CSP 规则要到 `meta` 标签被读取和处理后才会生效。

这是在没有 CSP 的情况下从 CodeProject 加载图像的 HTML。您可以将代码复制并粘贴到一个空的 HTML 文件中,并将其本地保存。

<html>
<head>
<title>CSP
in Action</title>
<head>
<body>
<p><img
src="https://codeproject.org.cn/App_Themes/CodeProject/Img/logo250x135.gif"
/>  </p>
</body>
</html>

通过双击文件管理器中的文件,在浏览器中查看 HTML,图像将从 CodeProject 下载并显示。

我们添加一个 CSP meta 标签。

<html>
<head>
<meta
http-equiv="Content-Security-Policy" content="default-src
'self';">
<title>CSP
in Action</title>
<head>
<body>
<p><img
src="https://codeproject.org.cn/App_Themes/CodeProject/Img/logo250x135.gif"
/>  </p>
</body>
</html>

现在尝试在浏览器中查看页面。

砰!现在显示了损坏的图像,表明该图像未被获取,因为 www.codeproject.com 不是同一来源域。在 Web 浏览器中按 **F12** 打开开发者工具,然后导航到控制台选项卡。在 Chrome 中,它会以红色显示此错误。

拒绝加载图像“https://codeproject.org.cn/App_Themes/CodeProject/Img/logo250x135.gif”,因为它违反了以下内容安全策略指令:“default-src 'self'”。请注意,未显式设置 'img-src',因此 'default-src' 被用作后备。

如前所述,我们通过 `default-src` 指令有效地将所有内容限制为使用 '`self`' 关键字的同一来源。

让我们在 `default-src` 后面追加一个空格,然后是 CodeProject URI。为简单起见,我只显示更新的 `meta` 标签,其余 HTML 保持不变。

<meta http-equiv="Content-Security-Policy" content="default-src 'self'
https://codeproject.org.cn;">

再次查看页面。现在显示了 CodeProject 图像。注意:`self` 关键字必须用单引号括起来,而 URI 则不需要。

在浏览器中查看页面。现在图像回来了。由于 gif 是图像资源,让我们进行一些重构,并将 CodeProject URI 放在 `img-src` 指令下。

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src 
https://codeproject.org.cn;">

再次在浏览器中查看页面。图像仍然出现。在此之前,没有指定 `img-src`。那么它的值是多少?答案是,当未指定时,它从 `default-src` 继承。注意:如果您的 URI 重定向到另一个域上的 URI,则该域也必须在 CSP 中。

CSP 指令

CSP 指令主要涵盖可以指定来源的的内容类型。本文涵盖了大多数指令。所有回退到 `default-src` 的指令都显示在下面的层级结构中。

  • `default-src`:当其他获取指令未明确指定时,它们的主要后备。
  • `child-src`:列出使用 `` 和 `