有没有办法允许Cloudflare的脚本出现在新的谷歌网站上



我使用新的谷歌网站(而不是经典网站(创建了一个网站,通过Cloudflare设置了网站代理,并在Cloudflare中启用了电子邮件地址混淆功能。然后我添加了一个执行简单操作mailto:info@example.com的按钮,遇到了一个问题:当我点击该按钮时,我被带到Cloudflare";电子邮件保护";带有消息"的页面;您无法访问此电子邮件地址example.com"。

原因很简单——我的浏览器(任何现代浏览器都会发生这种情况(没有从Cloudflare加载email-decode.min.js脚本。反过来,这是由于谷歌网站使用CSP>=v2和CSP指令的配置方式不允许从Cloudflare加载脚本。

根据Cloudflare文档,为了使用Scrape-Shield,您需要更新CSP标头,如下所示:

script-src 'self' 'unsafe-inline'

这就是新的谷歌站点CSP头的样子:

base-uri 'self';
object-src 'none';
report-uri /_/view/cspreport;
script-src 'report-sample' 'nonce-7+8CsMF6KihKnNmDwfM84w' 'unsafe-inline' 'unsafe-eval';
worker-src 'self';
frame-ancestors https://google-admin.corp.google.com/

*CCD_ 3随每个请求而更新。

当加载包含电子邮件的页面时,我在浏览器控制台中看到以下错误:

Refused to load the script 'https://example.com/cdn-cgi/scripts/6d6ddgh8/cloudflare-static/email-decode.min.js' because it violates the following Content Security Policy directive: "script-src 'report-sample' 'nonce-7+8CsMF6KihKnNmDwfM84w' 'unsafe-inline' 'unsafe-eval'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

我不确定原因,但由于以下两个原因之一,脚本无法加载:

  1. 没有为script-src指令设置源'self'(我不认为是这种情况(
  2. 'unsafe-inline'被忽略,因为存在加密随机数

无论如何都不起作用。我看到了两种解决方案,但我不知道如何实现它们:

  1. 出于第一个原因(尽管我不认为是这样(,如果谷歌将源'self'添加到script-src指令中,或者如果我有能力自定义这个头,我会自己做,这个问题就可以解决
  2. 第二个原因是,如果Cloudflare读取谷歌服务器在请求网站时返回的'nonce-<base64-value>'并将其添加到其脚本中,则可以解决此问题

如果有人能分享这个问题的解决方案,我们将不胜感激。

所以我发现原因是script-src指令中缺少'self'源。

我发现了一个论坛线程,建议使用Cloudflare Workers动态更改请求/响应中所需的数据。我还为一个工作人员找到了一个现成的示例代码,它允许替换请求/响应中的头。

受此想法的启发,鉴于Cloudflare每天免费提供100000个请求,我编写并部署了一个更改服务器响应标头的工作程序代码,事实上,它更新了content-security-policy标头中的script-src指令,并用变量sources中指定的源对其进行了补充。

我的问题解决了,现在Cloudflare脚本正在加载,按钮也在工作。

*我不承诺质量代码,但它有效。代码可以变得更加通用,但我没有时间。

这是我的员工代码:

addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request))
})
const sources = ["'self'"]
/**
* The function to update a CSP directive with new sources.
* @param {string} directive CSP directive.
* @param {string[]} sources Sources to add to the directive.
* @return {string} Updated CSP directive.
*/
function updateDirective(directive, sources) {
for (let i = 0; i < sources.length; i++) {
if (!directive.toLowerCase().includes(sources[i])) {
directive = directive.concat(" ", sources[i])
}
}

return directive
}
/**
* The function to update the Content-Security-Policy header.
* @param {string} header The Content-Security-Policy header.
* @param {string} directive The Content-Security-Policy directive whose sources need to be updated.
* @param {string} sources Sources to add to the directive.
* @return {string} Updated Content-Security-Policy header.
*/
function updateHeader(header, directive, sources) {
let sourceHeader = header.split(';')
let updatedHeader = []

for (let i = 0; i < sourceHeader.length; i++) {
if (sourceHeader[i].includes(directive)) {
updatedHeader.push(updateDirective(sourceHeader[i], sources))
} else {
updatedHeader.push(sourceHeader[i])
}
}

return updatedHeader.join(";")
}
async function handleRequest(request) {
let response = await fetch(request)
response = new Response(response.body, response)
response.headers.set('content-security-policy',
updateHeader(response.headers.get('content-security-policy'), "script-src", sources))
return response
}

相关内容

  • 没有找到相关文章

最新更新