内容安全策略 (CSP) 如何运作?

2024-03-20

我在开发者控制台中收到一堆错误:

拒绝评估字符串

拒绝执行内联脚本,因为它违反了以下内容安全策略指令

拒绝加载脚本

拒绝加载样式表

这是怎么回事?内容安全策略 (CSP) 如何运作?我该如何使用Content-Security-PolicyHTTP 标头?

具体来说,如何...

  1. ...允许多个来源吗?
  2. ...使用不同的指令?
  3. ...使用多个指令?
  4. ...处理端口?
  5. ...处理不同的协议?
  6. ...允许file://协议?
  7. ...使用内联样式、脚本和标签<style> and <script>?
  8. ...允许eval()?

最后:

  1. 到底是做什么的'self' mean?

The Content-Security-Policy元标记可以让您降低风险XSS http://en.wikipedia.org/wiki/Cross-site_scripting通过允许您定义可以从何处加载资源来防止浏览器从任何其他位置加载数据来攻击。这使得攻击者更难将恶意代码注入您的网站。

我把头撞在砖墙上,试图弄清楚为什么我会一次又一次地遇到 CSP 错误,但似乎没有任何简洁、清晰的说明来说明它是如何工作的。所以这是我尝试解释的some简要介绍一下 CSP 的要点,主要集中在我发现很难解决的问题上。

为了简洁起见,我不会在每个示例中编写完整的标签。相反,我只会显示content财产,所以一个样本说content="default-src 'self'"意思是这样的:

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

1. 如何允许多个来源?

您可以简单地在指令后以空格分隔的列表形式列出源:

content="default-src 'self' https://example.com/js/"

请注意,除了参数之外,参数周围没有引号special那些,比如'self'。另外,没有冒号(:) 指令之后。只是指令,然后是空格分隔的参数列表。

低于指定参数的所有内容都是隐式允许的。这意味着在上面的示例中,这些都是有效的来源:

https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js

然而,这些是无效的:

http://example.com/js/file.js
^^^^ wrong protocol

https://example.com/file.js
                   ^^ above the specified path

2. 如何使用不同的指令?他们各自做什么?

最常见的指令是:

  • default-src加载 javascript、图像、CSS、字体、AJAX 请求等的默认策略
  • script-src定义 javascript 文件的有效来源
  • style-src定义 css 文件的有效来源
  • img-src定义图像的有效来源
  • connect-src定义 XMLHttpRequest (AJAX)、WebSockets 或 EventSource 的有效目标。如果尝试连接到此处不允许的主机,浏览器将模拟400 error

还有其他的,但这些是您最可能需要的。

3. 如何使用多个指令?

您可以在一个元标记内定义所有指令,并用分号 (;):

content="default-src 'self' https://example.com/js/; style-src 'self'"

4. 如何处理端口?

除了默认端口之外的所有端口都需要通过在允许的域后添加端口号或星号来明确允许:

content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"

上述结果将导致:

https://ajax.googleapis.com:123
                           ^^^^ Not ok, wrong port

https://ajax.googleapis.com - OK

http://example.com/free/stuff/file.js
                 ^^ Not ok, only the port 123 is allowed

http://example.com:123/free/stuff/file.js - OK

正如我提到的,您还可以使用星号来明确允许所有端口:

content="default-src example.com:*"

5. 如何处理不同的协议?

默认情况下,仅允许标准协议。例如允许 WebSocketsws://你必须明确允许它:

content="default-src 'self'; connect-src ws:; style-src 'self'"
                                         ^^^ web Sockets are now allowed on all domains and ports.

6. 如何允许文件协议file://?

如果你试图这样定义它,那是行不通的。相反,您可以使用filesystem范围:

content="default-src filesystem"

7. 如何使用内联脚本和样式定义?

除非明确允许,否则不能使用内联样式定义、内部代码<script>标签或标签属性中,例如onclick。你允许他们这样:

content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"

您还必须明确允许内联、base64 编码的图像:

content="img-src data:"

8.我怎样才能允许eval()?

我相信很多人会说你不知道,因为“评估是邪恶的”并且最有可能导致世界末日即将到来。那些人就错了。当然,您绝对可以使用 eval 在站点的安全性上打出重大漏洞,但它具有完全有效的用例。您只需要聪明地使用它即可。你允许它像这样:

content="script-src 'unsafe-eval'"

9. 到底是什么'self' mean?

你可能会采取'self'表示本地主机、本地文件系统或同一主机上的任何内容。这并不意味着任何一个。这意味着源与定义内容策略的文件具有相同的方案(协议)、相同的主机和相同的端口。通过 HTTP 为您的站点提供服务?那么你就没有 https 了,除非你明确定义它。

我用过'self'在大多数示例中,因为包含它通常是有意义的,但它绝不是强制性的。如果不需要,请将其保留。

但请稍等!我不能只使用content="default-src *"就这样结束了吗?

不。除了明显的安全漏洞之外,这也不会像您期望的那样工作。虽然一些文档 http://content-security-policy.com/声称它允许任何事情,但事实并非如此。它不允许内联或评估,因此要真正使您的网站更加容易受到攻击,您可以使用以下命令:

content="default-src * 'unsafe-inline' 'unsafe-eval'"

...但我相信你不会。

进一步阅读:

http://content-security-policy.com http://content-security-policy.com

http://en.wikipedia.org/wiki/Content_Security_Policy http://en.wikipedia.org/wiki/Content_Security_Policy

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内容安全策略 (CSP) 如何运作? 的相关文章

随机推荐

  • 在 UI-Grid 标题中实现多列分组有更好的方法吗?

    我尝试使用以下方法在 UI Grid 的列标题级别实现多列分组 我遵循的步骤 包括 UI 网格的以下标题单元格模板以及另一个 UI 网格行 div class ui grid header custom ui grid header div
  • 在动态创建的 Web 应用服务中添加自定义域

    我使用 REST API 创建了 azure Web 应用程序 是否有任何选项可以使用rest api 自定义域映射 通过下面的链接 我创建了新的网络应用服务 https learn microsoft com en us rest api
  • Ionic 3 启用单页滑回功能

    我已在根组件和模块配置中全局禁用 向后滑动
  • 替换三元运算中已弃用的“define(@array)”

    我有以下需要更正的代码 如defined array 在最新的 Perl 中已弃用 my inputs defined padSrc gt inouts padSrc gt inouts defined padSrc gt inputs p
  • 从“void*”到“unsigned char*”的转换无效

    我有以下代码 void buffer operator new 100 unsigned char etherhead buffer 尝试编译时 我收到该行的以下错误 error invalid conversion from void t
  • 上下移动 ListViewItems

    我有一个 ListView WinForms 我想通过单击按钮来上下移动项目 要移动的项目是已检查的项目 因此 如果选择了第 2 6 和 9 项 当我按下向上移动按钮时 它们将变为 1 5 和 8 并且这些位置上的项目将向下移动一步 我觉得
  • 基于标签的 SQL 查询

    我已经有一段时间没有做过任何 SQL 了 我不确定这个问题是否有一个简单的解决方案 我也有点菜鸟 我正在尝试构建一个图像库 允许用户使用标签来搜索图像 然后单击其他标签来优化搜索并减少结果数量 但我在所涉及的查询方面遇到了大问题 这是我当前
  • 从 firebase Swift 加载聊天

    我目前正在做一个聊天信使 我能够检索我发送给其他用户的所有消息 但无法检索他们发送的任何消息 我用来加载消息的代码是 func loadMsg let toId user id let fromId Auth auth currentUse
  • CMake 不再找到静态 Boost 库

    我正在开发一个依赖 Boost 的大型 C 项目 该项目使用 CMake 在各种平台上构建 在我的 Windows 计算机上 我使用 CMake 2 8 9 Visual Studio 2010 和 Boost 1 50 0 从源代码构建
  • 从 Openlayers 3 视口获取所有功能

    我试图找出 Openlayers 3 中图层上可见的所有功能 视口 如果我向地图添加点击事件 我可以找到一个功能 如下所示 但我无法找到视口中可见的所有功能 有人可以帮忙解决这个问题吗 map on click function evt v
  • 如何使用geodjango返回距某个点最近距离的记录?

    我正在使用 geodjango 并在我的数据库中有一个点的集合 为了获取某个区域内的点的查询集 我使用以下命令 queryset Spot objects filter point distance lte origin distance
  • Android 使用包含另一个 hashmap 的 hashmap 实现 Parcelable 对象

    这是一个扩展Android 实现具有 hashmap 的 Parcelable 对象 https stackoverflow com questions 22498746 android implement parcelable objec
  • XSS 背后的一般概念是什么?

    跨站脚本 XSS 是一种类型 计算机安全漏洞 通常出现在网络应用程序中 这使得恶意攻击者能够 将客户端脚本注入网络 其他用户查看的页面 一个 利用跨站点脚本 漏洞可被攻击者利用 绕过访问控制 例如 同源政策 跨站点 在网站上执行的脚本是 大
  • RXJava - 制作一个可暂停的可观察对象(例如带有缓冲区和窗口)

    我想创建执行以下操作的可观察对象 在暂停时缓冲所有项目 立即发出项目 同时它们不会暂停 暂停 恢复触发器必须来自另一个可观察的 必须保存它才能供不在主线程上运行的可观察对象使用 并且必须保存更改主线程的暂停 恢复状态 我想用一个Behavi
  • Android - Firebase - 我需要删除每个侦听器吗?

    我做了相当多的研究 但找不到我需要的答案 我所知道的是 当我将 ValueEventListener 附加到数据库引用时 我知道稍后需要将其删除 现在发现很难解决 因为存在大量内存泄漏 我不知道的是 我还需要分离所有其他侦听器吗 这包括 F
  • java.lang.RuntimeException:android.os.TransactionTooLargeException:在片段之间导航时数据包大小 558780 字节

    我在用Bundle在活动和片段之间传输数据 当我从一个片段导航到新片段时 不传输数据或使用Bundle为了获取数据 应用程序崩溃并出现以下错误 gt gt 10 09 11 36 09 100 467 467 E JavaBinder FA
  • FragmentStatePagerAdapter 处理 getItem() 位置

    我尝试了这个 但错误的列表被绑定到回收器视图 我也尝试过 SparseArray 即使这样也不起作用 当我启动 Mainactivity 时 getItem 被调用两次 退回的仓位如何处理 我尝试返回 viewpager currentIt
  • JavaScript 未定义替换为 null

    在 JavaScript 中undefined可以重新分配 因此通常建议创建一个自执行函数 以确保 undefined 实际上是未定义的 作为备选null and undefined肯定是 但任何其他值都大致相当于null undefine
  • 无法在主机上创建 node_modules 文件夹并将主机文件夹挂载到容器

    我的 dockerfile 将运行 npm install 但是之后docker compose build即使在看到构建后 我的主机文件夹中的文件夹 node modules 仍然为空 我怎样才能获得该文件夹并反映在主机中 这是 dock
  • 内容安全策略 (CSP) 如何运作?

    我在开发者控制台中收到一堆错误 拒绝评估字符串 拒绝执行内联脚本 因为它违反了以下内容安全策略指令 拒绝加载脚本 拒绝加载样式表 这是怎么回事 内容安全策略 CSP 如何运作 我该如何使用Content Security PolicyHTT