NextCloud下的CSP配置问题
一转眼发现约1个月没有写博客了这两天又比较烦,需要学习的东西太多了,可惜人的精力不是无限的。
前几天想登陆自己搭建的网盘看看,结果发现网盘的登陆界面显示不出来,这时候就把控制台打开看了看,发现有报错,大概意思就是来自ajax.cloudflare.com的js脚本不被信任,所以这个无法加载这个js资源,产生这个问题的原因——在cloudflare的DNS设置界面将对应网站的DNS解析设置为了代理,而非仅DNS,所以最简单的方法就是将cloudflare的DNS修改为仅DNS,这时候cloudflare的对应界面云朵应该是灰色,而非之前的黄色,现在当你访问对应页面的时候网站资源就不会在前端被cloudflare注入相应脚本了。
不过设置仅限了DNS之后,cloudflare会提示有IP被暴露的风险,强迫症患者决定找到解决这个问题的更好的方式,其实问题的 最根本原因就是来自cloudflare域的脚本不再headers提供的CSP信任域里面,为了防止跨站攻击,浏览器就自动不会加载这一类脚本,关于CSP的相关内容,可以参考谷歌提供的内容安全性政策(CSP)页面,其说明了CSP的作用和配置格式。
既然找到了问题原因所在,现在考虑一下怎么解决问题。根据谷歌的开发者文档,解决方案也就是两个:
- 添加对应的CSP信任规则到头文件中(推荐这种方式,而且个人认为这才是解决问题的正确方式)
- 在网页标签下添加信任域
经过试验后,方案1失败了,通过相关网站对我的网站评测,发现我的网站CSP被配置了这种规则,但是我在nginx并没有进行相关配置,于是猜测这是Nextcloud生成的CSP规则,查阅资料发现,Nextcloud的CSP生成代码在~/lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php
内(我的Nextcloud版本为21.0.1),阅读代码,发现在该PHP文件的434行之后的代码即是生成CSP规则的,截取生成script-src 部分的
if (!empty($this->allowedScriptDomains) || $this->inlineScriptAllowed || $this->evalScriptAllowed) {
$policy .= 'script-src ';
if (is_string($this->useJsNonce)) {
$policy .= '\'nonce-'.base64_encode($this->useJsNonce).'\'';
$allowedScriptDomains = array_flip($this->allowedScriptDomains);
unset($allowedScriptDomains['\'self\'']);
$this->allowedScriptDomains = array_flip($allowedScriptDomains);
if (count($allowedScriptDomains) !== 0) {
$policy .= ' ';
}
}
if (is_array($this->allowedScriptDomains)) {
$policy .= implode(' ', $this->allowedScriptDomains);
}
if ($this->inlineScriptAllowed) {
$policy .= ' \'unsafe-inline\'';
}
if ($this->evalScriptAllowed) {
$policy .= ' \'unsafe-eval\'';
}
$policy .= ';';
}
后来参考了修复nextcloud和cloudflare一起用时候的无法登陆问题,其实从cloudflare设置相应的页面规则就可以解决问题,一般选择“绕过缓存和禁用性能”即可。
如果你认为这篇文章还不错,可以考虑 为作者充电 ⚡️