Safari 出现错误 "Refused to connect to _____ because it does not appear in the connect-src directive of the Content Security Policy."

Safari Gives Error "Refused to connect to _____ because it does not appear in the connect-src directive of the Content Security Policy."

我有一个 Safari 用户无法连接的在线白板。他们从控制台获得以下信息。

Refused to connect to wss://whiteboard.[MYDOMAIN].com/[MOREPATHSTUFF] because it does not appear in the connect-src directive of the Content Security Policy.

只有 Safari 可以做到这一点。 Chrome、FF、Edge 等工作正常。我查看了其他与 SO 相关的帖子,似乎 Safari 需要类似...

<meta http-equiv="Content-Security-Policy" content="
                        default-src * data: blob: ws: wss: gap://ready file://*;
                        style-src * 'unsafe-inline'; 
                        script-src * 'unsafe-inline' 'unsafe-eval';
                        connect-src * ws: wss:;">

虽然我不知道这一切意味着什么。我想要的只是让 Safari 允许连接,一切都应该很好。感谢您考虑如何实现这一目标。

CSP 有一些不直观的特征。一个是: wss://example.com 等 Websocket 不会被 *.example.com 甚至 *

等通配符捕获

为了允许 websockets - 您需要使用 wss://example.com 甚至 ws: wss:

显式添加它们

如果您只想允许 connect-src 上的任何内容,则添加 connect-src * ws: wss:; 您的政策应该有效(如您所述)。

I've looked over other SO related posts and it seems that Safari requires something like...

您已经通过 HTTP header 或元标记 (how to check it) 发布了内容安全策略 (CSP),因为浏览器控制台中会显示违规消息。
发布第二个 CSP 不能放宽由此产生的策略,因为第一个 CSP 仍然会执行阻塞。
这就是为什么您无法通过添加元标记或 HTTP header.

来解决问题的原因

您必须找出第一个 CSP 的发布位置并对其进行更改。

Only Safari does this. Chrome, FF, Edge, etc. work fine.

Safari 支持 connect-src 指令,因此它的行为应该与 Chrome/Firefox/Edge 没有区别,除了一件事:Safari 会 not supportws: 升级到 wss: .
connect-src ws: 的情况下,Chrome/Firefox/Edge 将应用 connect-src ws: wss: 策略,但 Safari 不会。

我打赌你在 CSP 中有 connect-src ws:,因此到 wss: 的所有连接都被阻止了。
当您找到 CSS 的发布位置时,只需将 wss://whiteboard.[MYDOMAIN].com 添加到 connect-src 指令即可。

注意:如果您使用 default-src 指令而不是 connect-src - 那么您需要将 wss://whiteboard.[MYDOMAIN].com 添加到其中。

更新:
如何发行 CSP header

A)。 CSP header 可以在您的 Web 应用程序本身中发布(头盔中间件、用于管理 HTTP header 的特定包、通过 res.setHeader() 直接发布 HTTP header 等等) .

B)。 CSP header 可以由服务器发布。对于 Nginx,它在服务器配置中应该是 add_header Content-Security-Policy "default-src ... ";Several folders can be used for that but etc/nginx/conf.d 是首选,其他的已弃用。

如果我同时以 A) 和 B) 两种方式发布 CSP header 会怎么样?

服务器工作你的网络应用程序软件完成所有工作后,因此web-server(或proxy-server)应该覆盖HTTP header同名。因此服务器可以覆盖网络应用程序发布的任何 HTTP header。

在某些情况下它不起作用,您可以看到 2 CSP headers been published. Even in this case you can make a trick:

proxy_hide_header Content-Security-Policy;

然后紧接着在下面添加 header 您需要它的方式:

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

这可以用作临时解决方案,直到您弄清楚 header 的实际发布位置。