如何发送报告 API 报告 cross-origin (Report-To) header
How to send Reporting API reports cross-origin (Report-To) header
我有一个 API 收集内容安全策略 (CSP) 违规报告。现在 report-uri
被 report-to
指令取代,我打算使用它。但是,我无法获得报告 cross-origin。我试过使用 cors
包。但是还是拿不到报告。
我在客户端源上设置的headers(示例-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
(这适用于同源)
在 server-side(示例-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();
});
我没有收到来自跨源的报告。请将我视为初学者,让我知道我在哪里犯了错误。谢谢。
CSP 报告 API 不是 CORS 的主题,因为没有从服务器加载资源。浏览器只是发送一个报告,并不期望来自 CSP 报告 API 的任何 headers/response。要显示这一点,您 return 204 No content
header 以便浏览器不期望响应。
为什么您认为您有 CORS 问题? 当您通过 Cloudflare.com 代理站点时,它会在所有页面中注入一个 NEL/Report-to
(与 CSP/Report-to
) headers 相同,具有 CF 自己的域,没有任何 CORS 问题:
我已经为 report-uri
实现了很多端点并且从未遇到过任何 CORS 问题。
请注意 report-uri
已过时以支持 report-to
指令,但浏览器不支持 report-to
除了 Chrome.
当您出于测试目的模拟发送报告时,请勿使用普通的 ajax POST 请求 - 它受 CORS 约束。
要模拟发送真实报告,请在 third-party 域上生成一个页面:
<script>alert('inline success')</script>
并用 CSP 发送 header:
Content-Security-Policy: "default-src 'report-sample' report-uri https://your_reporting_api.com/endpoint;"
调试时使用 report-uri
比 report-to
更容易。
配置 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 说明:打开开发者工具,点击齿轮图标进行设置,在“实验”下有一个选项标记为“在应用程序面板中启用报告 API 面板”)
您的代码似乎是正确的,但目前在 Chrome/Chromium 为报告 API 实施 CORS 时存在错误,这很可能是您遇到问题的原因。参见 Chromium issue #1152867。该错误的要点是此处使用的 CORS 实现要求响应中存在 Access-Control-Allow-Methods: POST
header,这不符合 CORS 规范,因为 POST
是一个“简单”方法。
如果您能够修改服务器上的 CORS 实现,则可以将其修改为始终在 OPTIONS
响应中包含 Access-Control-Allow-Methods: POST
header,这应该可以解决错误。
否则,您将不得不要么不使用 cross-domain 报告请求,要么退回到仅使用已弃用的 Report-Uri
指令,直到修复发布。后者应该不是什么大问题,因为 Firefox 和 Safari 无论如何都不支持新的 Report-To
header。
我有一个 API 收集内容安全策略 (CSP) 违规报告。现在 report-uri
被 report-to
指令取代,我打算使用它。但是,我无法获得报告 cross-origin。我试过使用 cors
包。但是还是拿不到报告。
我在客户端源上设置的headers(示例-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
(这适用于同源)
在 server-side(示例-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();
});
我没有收到来自跨源的报告。请将我视为初学者,让我知道我在哪里犯了错误。谢谢。
CSP 报告 API 不是 CORS 的主题,因为没有从服务器加载资源。浏览器只是发送一个报告,并不期望来自 CSP 报告 API 的任何 headers/response。要显示这一点,您 return 204 No content
header 以便浏览器不期望响应。
为什么您认为您有 CORS 问题? 当您通过 Cloudflare.com 代理站点时,它会在所有页面中注入一个 NEL/Report-to
(与 CSP/Report-to
) headers 相同,具有 CF 自己的域,没有任何 CORS 问题:
report-uri
实现了很多端点并且从未遇到过任何 CORS 问题。
请注意 report-uri
已过时以支持 report-to
指令,但浏览器不支持 report-to
除了 Chrome.
当您出于测试目的模拟发送报告时,请勿使用普通的 ajax POST 请求 - 它受 CORS 约束。
要模拟发送真实报告,请在 third-party 域上生成一个页面:
<script>alert('inline success')</script>
并用 CSP 发送 header:
Content-Security-Policy: "default-src 'report-sample' report-uri https://your_reporting_api.com/endpoint;"
调试时使用 report-uri
比 report-to
更容易。
配置 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 说明:打开开发者工具,点击齿轮图标进行设置,在“实验”下有一个选项标记为“在应用程序面板中启用报告 API 面板”)
您的代码似乎是正确的,但目前在 Chrome/Chromium 为报告 API 实施 CORS 时存在错误,这很可能是您遇到问题的原因。参见 Chromium issue #1152867。该错误的要点是此处使用的 CORS 实现要求响应中存在 Access-Control-Allow-Methods: POST
header,这不符合 CORS 规范,因为 POST
是一个“简单”方法。
如果您能够修改服务器上的 CORS 实现,则可以将其修改为始终在 OPTIONS
响应中包含 Access-Control-Allow-Methods: POST
header,这应该可以解决错误。
否则,您将不得不要么不使用 cross-domain 报告请求,要么退回到仅使用已弃用的 Report-Uri
指令,直到修复发布。后者应该不是什么大问题,因为 Firefox 和 Safari 无论如何都不支持新的 Report-To
header。