Search code examples
node.jsexpressgoogle-chromecontent-security-policypreflight

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


I have an API which collects Content Security Policy (CSP) violation reports. Now that report-uri is being replaced by report-to directive, I planned to use that. However, I'm unable to get reports cross-origin. I've tried using the cors package. But still unable to get the report.

The headers I have set on client origin (example-1.com) are:

res.setHeader(
    'Report-To',
    '{"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url": "https://example-2.com/csp-report"}]}'
);

In CSP, the report-to value is set to csp-endpoint (This is working on same origin)

On server-side (example-2.com), the following code is present (Express.js server):

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();
});

I'm not getting reports from cross origin. Please consider me a beginner and let me know where I'm making mistake. Thanks.


Solution

  • Your code appears to be correct, but there is currently a bug in Chrome/Chromium's implementation of CORS for the Reporting API, which is likely to be causing your problem. See Chromium issue #1152867. The gist of the bug is that the CORS implementation used here requires that an Access-Control-Allow-Methods: POST header exists on the response, which is not compliant with the CORS spec, as POST is a "simple" method.

    If you are able to modify the CORS implementation on your server, you can modify it to always include the Access-Control-Allow-Methods: POST header on the OPTIONS response, which should work around the bug.

    Otherwise, you will have to either not use a cross-domain request for reporting, or fall back to only using the deprecated Report-Uri directive until the fix is released. The latter shouldn't be too much of an issue, as Firefox and Safari don't support the new Report-To header yet anyway.