Security headers sent from the backend while the frontend is hosted separately

288 views Asked by At

Is there any value in sending security headers like Content-Security-Policy (I am mainly thinking of using Helmetjs) from the backend, if it is used as an APIs and the frontend is served separately by a hosting service?

I tried things locally and found out those headers don't seem to work unless I server the frontend from the backend, e.g. Expressjs serving static files.

Is this the case or am I missing something?

2

There are 2 answers

0
Marek Puchalski On

Yes, it does. Many security headers like the mentioned CSP, but also many others, are client-side controls which are implemented on the server side. CSP is quite a complex header to use. It tells for example which JS-files (files from which domain) may be executed and which not or which backend the communication may take place with. As you may already expect, doing a misconfiguration will crash your whole application. The solution is not to give up, but to push through. For big systems it takes years before they are able to fully embrace CSP with all their contents with decent configuration.

Just remember, CSP has got the feature of reporting issues instead of blocking them (Content-Security-Policy-Report-Only). Make sure you use this first before you implement something you may regret.

0
Evan Hahn On

Short answer: I recommend setting security headers on the frontend and backend (though the frontend is probably more important).

Helmet maintainer here.

Let's say you visit app.example.net and it makes some requests to api.example.net. In this example, app.example.net serves HTML and api.example.net serves JSON.

If you want Content-Security-Policy protections, you should set the header on app.example.net—it doesn't matter what api.example.net does. The same is true for many other security headers like Referrer-Policy.

However, not all security headers work this way. Strict-Transport-Security, for example, could be useful on api.example.net because it tells the browser to maintain a secure HTTPS connection. Other headers might be useful too, like X-Content-Type-Options and X-Permitted-Cross-Domain-Policies.

You may wish to read this recent question on the Helmet repository which delves into a closely-related problem.