如何发送 Reporting API 报告跨域 (Report-To) 标头
Posted
技术标签:
【中文标题】如何发送 Reporting API 报告跨域 (Report-To) 标头【英文标题】:How to send Reporting API reports cross-origin (Report-To) header 【发布时间】:2022-01-12 06:39:39 【问题描述】:我有一个用于收集内容安全策略 (CSP) 违规报告的 API。现在report-uri
被report-to
指令取代,我打算使用它。但是,我无法获得跨域报告。我试过使用cors
包。但仍然无法得到报告。
我在客户端来源(example-1.com)上设置的标题是:
res.setHeader(
'Report-To',
'"group":"csp-endpoint","max_age":10886400,"endpoints":["url": "https://example-2.com/csp-report"]'
);
在 CSP 中,report-to
值设置为 csp-endpoint
(这是在同源上工作)
在服务器端(example-2.com),存在以下代码(Express.js 服务器):
app.use(
'/csp-report',
express.json(
type: [
'application/json',
'application/csp-report',
'application/reports+json'
]
)
);
app.use('/csp-report', cors()) // Using cors npm package
app.post('/csp-report', (req, res) =>
res.setHeader('Access-Control-Expose-Headers', '*, Authorization');
console.log(req.headers);
console.log('CSP Violation Timestamp : ' + new Date().getTime());
console.log(req.body);
res.status(204).send();
);
我没有收到来自跨域的报告。请把我当作初学者,让我知道我在哪里犯错。谢谢。
【问题讨论】:
【参考方案1】:您的代码似乎是正确的,但目前在 Chrome/Chromium 的 Reporting API 的 CORS 实现中存在错误,这可能会导致您的问题。见Chromium issue #1152867。该错误的要点是此处使用的 CORS 实现要求响应中存在 Access-Control-Allow-Methods: POST
标头,这不符合 CORS 规范,因为 POST
是一种“简单”方法。
如果您能够修改服务器上的 CORS 实现,则可以将其修改为始终在 OPTIONS
响应中包含 Access-Control-Allow-Methods: POST
标头,这应该可以解决该错误。
否则,您必须要么不使用跨域报告请求,要么回退到仅使用已弃用的 Report-Uri
指令,直到修复发布。后者应该不是太大的问题,因为 Firefox 和 Safari 还不支持新的 Report-To
标头。
【讨论】:
这就是我要找的。非常感谢。【参考方案2】:当配置了report-to
指令时,CSP 报告将使用Reporting API 发送报告。在这种情况下,浏览器将要求 CORS 用于跨域报告,并且您的服务器可能未正确配置为在该 URL 上协商 CORS。 (我不知道您正在使用的 npm 包的详细信息,但这是我的怀疑)。
浏览器会发送表单的飞行前请求:
OPTIONS /csp-report HTTP/1.1
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Origin: example-1.com
您的服务器需要响应如下内容:
200 OK HTTP/1.1
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: example.com
Access-Control-Max-Age: 3600
如果发生这种情况,则会发送第二个请求(带有实际报告)。
Chrome NetLog viewer 可用于调试此类问题。
此外,最新版本的 Chrome 在 DevTools for Reporting 中提供实验性支持。您应该能够看到已配置的端点以及已排队的报告。 (Chrome 96说明:打开devtools,点击齿轮图标进行设置,在“experiments”下有一个标签为“Enable Reporting API panel in the Application panel”的选项)
【讨论】:
我允许这些标题。它仍然无法正常工作。此外,NetLog 查看器只是显示它失败了。它没有显示它看起来的原因。【参考方案3】:CSP 报告 API 不是 CORS 的主题,因为没有从服务器加载任何资源。浏览器只是发送一个报告,并不期望来自 CSP 报告 API 的任何标题/响应。为了显示这一点,您返回 204 No content
标头,这样浏览器就不会期待响应。
你为什么认为你有 CORS 问题? 当你通过 Cloudflare.com 代理站点时,它会在所有页面中注入带有 CF 的 NEL/Report-to
(与 CSP/Report-to
相同)标头没有任何 CORS 问题的自己的域:
我已经为 report-uri
实现了很多端点,并且从未遇到任何 CORS 问题。
请注意,report-uri
已过时,取而代之的是 report-to
指令,但浏览器不支持 report-to
,Chrome 除外。
当您出于测试目的模拟发送报告时,请勿使用普通的 ajax POST 请求 - 它受 CORS 约束。 模拟发送真实报告,在第三方域上生成一个页面:
<script>alert('inline success')</script>
并与 CSP 标头一起发送:
Content-Security-Policy: "default-src 'report-sample' report-uri https://your_reporting_api.com/endpoint;"
在调试时,使用report-uri
而不是report-to
更容易。
【讨论】:
我正在返回 204 标头,但它似乎仍然不适用于其他来源。它只会成功发送相同来源的报告。 我已经用一些相关信息更新了答案。我的问题仍然有效:您为什么认为您有 CORS 问题? 请注意,您还可以使用 Fiddler 来监视错误报告,或配置 NetLog 捕获:textslashplain.com/2020/01/17/… 并查看查看器中的“报告”选项卡netlog-viewer.appspot.com/#import @granty 查看此链接:developers.google.com/web/updates/2018/09/reportingapi。这清楚地表明Note: If your endpoint URL lives on a different origin than your site, the endpoint should support CORs preflight requests. (e.g. Access-Control-Allow-Origin: *; Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS; Access-Control-Allow-Headers: Content-Type, Authorization, Content-Length, X-Requested-With
@EricLaw 我尝试了 NetLog 捕获。但是,它只显示请求失败。它没有显示发生了什么错误。以上是关于如何发送 Reporting API 报告跨域 (Report-To) 标头的主要内容,如果未能解决你的问题,请参考以下文章
Google Analytics Reporting Api - PHP:添加用户帐户