如何发送报告 API 报告 cross-origin (Report-To) header

How to send Reporting API reports cross-origin (Report-To) header

我有一个 API 收集内容安全策略 (CSP) 违规报告。现在 report-urireport-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-urireport-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。