NetEscapades.AspNetCore.SecurityHeaders icon indicating copy to clipboard operation
NetEscapades.AspNetCore.SecurityHeaders copied to clipboard

Question: Response Headers missing in API calls

Open damienbod opened this issue 1 year ago • 6 comments

I try to lock down my APIs the headers are not applied to API calls.

Looking into this now, maybe you have already experienced this.

Here's a repo to reproduce:

https://github.com/damienbod/AzureAD-Auth-MyUI-with-MyAPI/blob/main/MyApi/Program.cs

Greetings Damien

damienbod avatar Mar 11 '23 08:03 damienbod

I was missing the ApplyDocumentHeadersToAllResponses

policy.ApplyDocumentHeadersToAllResponses();

I wondering if it is a good idea not just to apply this per default?

damienbod avatar Mar 11 '23 08:03 damienbod

Hi Damien!

So hopefully previously you only saw some of the headers not being applied to API requests. Some headers don't make sense to apply to APIs generally (e.g. a CSP doesn't make sense for a JSON response) so by default, you won't get those on the API. You should still get some headers applied automatically.

The ApplyDocumentHeadersToAllResponses() method is really intended as a "compliance requires you add these headers, even though they don't do anything" on API requests feature 😉

So based on your sample, you should still have seen the following:

  • X-Content-Type-Options
  • Cross-Origin-Resource-Policy
  • Cross-Origin-Embedder-Policy
  • server header removed

If you didn't, there's definitely a bug.

I wondering if it is a good idea not just to apply this per default?

I'm a little torn. On the one hand, adding them doesn't hurt so why not? Pit of success and all.

But these headers are big, or at least they can be. CSP and permissions policy specifically can be very large. That's a lot of extra bytes for every request, especially for APIs which may need to be very fast. The extra bytes could mean extra packets etc where they wouldn't previously.

My inclination initially was that it's currently best of both worlds - you get all the headers you need, and no more. But if people think it's not working, or there's a bug, then it's probably the wrong default. I'm undecided!

andrewlock avatar Mar 11 '23 12:03 andrewlock

Hi Andrew

Thanks for your answer. It works just like you explain. I think it does make sense to add this as we use cookies now to access some APIs and maybe iframes might be used. I think locking this down per default would be good and a modern CSP can be reduced in size with strict-dynamic etc.

Fully understand these concerns.

Greetings Damien

damienbod avatar Mar 11 '23 14:03 damienbod

I think it does make sense to add this as we use cookies now to access some APIs and maybe iframes might be used.

As I understand it, that still doesn't apply here, right? All of the "missing" headers apply to the Document only, not to the JSON responses.

So in your example "iframe" case, I assume you are loading a top-level HTML document, and then loading an HTML (or JavaScript) file in the iframe, which in turn calls out to the API, correct? For this situation the CSP headers (and other "document" headers) on the API calls are ignored/don't do anything; it's only the CSP on the top-level document and the iframe document that matter. So in this case, adding the CSP to the JSON calls bloats the response without performing any security purpose.

Unless I've misunderstood of course! 😅

andrewlock avatar Mar 11 '23 17:03 andrewlock

I am unsure and don't know as well :) I will research this and try to understand. Thanks for your answers as well, really appreciate them.

Reading some docs and stack overflows and I am still unsure. I wondering if there is a way of attacking this and also wondering if the default defined types which the full headers are not applied can be used in a different way where the headers would protect then.

Greetings Damien

damienbod avatar Mar 12 '23 07:03 damienbod

If it helps OWASP does recommend the following:

The following headers should be included in all API responses:

Header Rationale
Cache-Control: no-store Prevent sensitive information from being cached.
Content-Security-Policy: frame-ancestors 'none' To protect against drag-and-drop style clickjacking attacks.
Content-Type To specify the content type of the response. This should be application/json for JSON responses.
Strict-Transport-Security To require connections over HTTPS and to protect against spoofed certificates.
X-Content-Type-Options: nosniff To prevent browsers from performing MIME sniffing, and inappropriately interpreting responses as HTML.
X-Frame-Options: DENY To protect against drag-and-drop style clickjacking attacks.

lankymart avatar Jun 02 '23 15:06 lankymart