Home > Back-end >  How to send Reporting API reports cross-origin (Report-To) header
How to send Reporting API reports cross-origin (Report-To) header

Time:12-08

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.

CodePudding user response:

CSP reporting API is not a subject of CORS, because no resources are loaded from the server. Browser just send a report and does not expect any headers/response from CSP reporting API. To show this you return the 204 No content header so that the browser does not expect a response.

Why do you think that you have a CORS issue? When you proxying site via Cloudflare.com, it injects into all pages a NEL/Report-to (the same as CSP/Report-to) headers with CF's own domain without any CORS issue: enter image description here I had implemented a lot of reporting API endpoints and never face any CORS issues.

Note that report-uri is obsolete in favour report-to directive, but browsers does not supports report-to except Chrome.

When you simulate sending a report for testing purposes, do not use an ordinary ajax POST request - it is subject to CORS.
To imitate sending real report, generate a page on third-party domain:

<script>alert('inline success')</script>

and send it with CSP header:

Content-Security-Policy: "default-src 'report-sample' report-uri https://your_reporting_api.com/endpoint;"

When debug it's easier to use report-uri not report-to.

CodePudding user response:

When configured with a report-to directive, CSP reports will use the Reporting API to send the reports. The browser will require CORS for cross-origin reports in that case, and it's possible that your server is not correctly configured to negotiate CORS on that URL. (I don't know the details of the npm package you're using, but that would be my suspicion).

The browser will send a pre-flight request of the form:

OPTIONS /csp-report HTTP/1.1
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Origin: example-1.com

And your server needs to respond with something like:

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

If that happens, then the second request (with the actual report) will be sent.

The Chrome NetLog viewer can be useful for debugging these sorts of problems.

As well, recent versions of Chrome have experimental support in DevTools for Reporting. You should be able to see configured endpoints, as well as reports which have been queued. (Chrome 96 instructions: Open devtools, click the gear icon for settings, and under "experiments" there is an option labeled "Enable Reporting API panel in the Application panel")

  • Related