在 nginx 中添加 Content-Security-Policy 后 websocket 连接失败
Posted
技术标签:
【中文标题】在 nginx 中添加 Content-Security-Policy 后 websocket 连接失败【英文标题】:websocket connection fails after adding Content-Security-Policy in nginx 【发布时间】:2021-11-20 14:00:53 【问题描述】:我想在我的 nginx conf 中添加一个新的标头 Content-Security-Policy 以提高安全性。我已经添加了所有外部资源并且一切正常,除了聊天机器人是 infobip。它使用 wss 协议,由于某种原因我找不到正确的配置方法。
This is the error that I get.
这是我在 nginx.conf 中的头文件
add_header 'Content-Security-Policy' "default-src 'self' 'unsafe-inline' wss: wss://.infobip.com ws://.infobip.com .infobip.com http://www.w3.org https://fonts.googleapis.com https://stackpath.bootstrapcdn.com .youtube.com https://cdn.jsdelivr.net/; img-src 'self' 数据:https://.openstreetmap.org wss://livechat- fr.infobip.com/chat/web/proxy/827/toxgylwd/websocket 总是;connect-src 'self' wss: ws: wss://.infobip.com ws://*.infobip.com .infobip.com https://.doubleclick.net wss://livechat-fr.infobip.com/chat/web/proxy/492/hybzmnjl/websocket 'unsafe-inline' 总是;" ;
我尝试了多种方法来允许 websocket 连接,但似乎都没有。
【问题讨论】:
【参考方案1】:由于每个 websocket 连接都是由一个常规的 http 请求开始的,你必须为 https://your-websocket-server-domain:port 添加一个 CSP
http 请求会得到一个101: swtiching protocols
的响应,然后这个连接就会变成一个WebSocket 连接。
请注意,我认为根本不需要 ws: 或 wss: csp 指令。
【讨论】:
【参考方案2】:您有 3 个问题:
您显示的控制台错误与 CSP 无关。 “403 Forbidden”表示您无权访问相关网址。 “'X-Frame-Options' to 'deny'”表示您尝试嵌入 iframe,但该页面不允许通过 X-Frame-Options: "DENY"
HTTP 标头嵌入。
Nginx add_header
格式错误。它应该看起来像(注意引号 - always
关键字应该放在 CSP 设置之外):
add_header Content-Security-Policy "default-src 'self'..." always;
Wrong CSP 的主机源格式。像 .youtube.com
这样的主机源不得包含前导 .
点:youtube.com
将允许从 http(s)://youtube.com 和 *.youtube.com
加载资源将允许来自 youtube.com 子域的资源。
所以你的语法正确的 CSP 应该如下所示:
add_header Content-Security-Policy "\
default-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com\
https://fonts.googleapis.com infobip.com ws://infobip.com wss://infobip.com youtube.com\
https://cdn.jsdelivr.net http://www.w3.org;\
connect-src 'self' infobip.com wss://infobip.com ws://*.infobip.com\
wss://livechat-fr.infobip.com/chat/web/proxy/ https://doubleclick.net;\
img-src 'self' data: https://openstreetmap.org;\
" always;
注意:
wss://livechat-fr.infobip.com/chat/web/proxy/492/hybzmnjl/websocket - 不要包含 CSP 的粗体路径部分,因为它每次都会更改。wss:
之类的方案源涵盖了具有该方案的任何主机源(例如 wss://site.com/websocket)。所以我删除了方案源并离开了主机源。
我删除了一些不受支持的来源,例如connect-src
中的'unsafe-inline'
。
Nginx 应该支持反斜杠\
作为换行符,所以我使用它是因为很难在一行中维护 CSP。检查您的 Nginx 版本是否支持此功能。
注意 2:此 CSP 可以阻止某些来源 - 只需将它们添加到适当的指令中即可。
注意 3: 考虑将源代码从 default-src
指令移至 script-src
+ style-src
+ font-src
指令。因为现在你实际上在scrit-src
中允许'unsafe-inline'
,所以你的CSP 不能防止XSS。未来管理 CSP 也将变得困难,因为源混合在一个指令中。
【讨论】:
谢谢,但不幸的是我仍然遇到同样的错误 - WebSocket 连接到...失败。我还得到:拒绝在框架中显示“livechat-fr.infobip.com”,因为它将“X-Frame-Options”设置为“拒绝”。这就是我始终设置标题 add_header 'X-Frame-Options' "SAMEORIGIN" 的方式; 您在服务器上设置了X-Frame-Options "SAMEORIGIN"
,但您的服务器不提供livechat-fr.infobip.com
被阻止。这是livechat-fr.infobip.com
发布X-Frame-Options "DENY"
标头以防止嵌入。您可能在您的 infobip.com
帐户中配置错误。
问题已解决。 CSP 指令工作正常。事实证明,公司网络正在阻止来自/到 infobip 的流量,而我没有被告知这一点。再次感谢您的努力,仍然帮助我制定了严格的指令。以上是关于在 nginx 中添加 Content-Security-Policy 后 websocket 连接失败的主要内容,如果未能解决你的问题,请参考以下文章