nuxt-security icon indicating copy to clipboard operation
nuxt-security copied to clipboard

Move meta charset back to top

Open frederikheld opened this issue 1 year ago • 9 comments

I just added the nuxt-security plugin to my Nuxt project and am using the configuration as it comes out of the box.

Problem: Nuxt adds the CSP meta tag as first element in head. This is a problem because Google Lighthouse will (rightfully!) complain that "Charset declaration is missing or occurs too late in the HTML".

Initially, I had charset defined in useSeoMeta, then moved it to useHead and finally moved it to the app section nuxt.config.ts. None of this moved the meta charset tag back to the top of head. The meta CSP tag always stays the first element.

As I also could not find any information about this issue in the nuxt-security docs, I'm asking this question here:

How can I move meta charset back to the top of head?

frederikheld avatar May 07 '24 10:05 frederikheld

Hi @frederikheld We insert CSP meta as first tag in head to conform to the Mozilla security recommendations: https://infosec.mozilla.org/guidelines/web_security#implementation-notes

@Baroshem what's your view on this one ? As I understand, this seems to conflict with Lighthouse. We could provide an option to insert it later ?

vejja avatar May 07 '24 10:05 vejja

Ah, I see, we have competing recommendations here. But I think that Mozilla is wrong here. The meta tag defines how the rest of the content should be interpreted so it should go first.

According to the W3C spec for HTML4, the browser will treat anything before the meta charset tag as ISO-8859-1. So we should make sure that nothing of relevance comes before it.

The W3C spec for HTML5 mentions that the document needs to have a meta charset tag (it is not optional like it was in HTML4) and it needs to appear within the first 1024 bytes of the document. I think this is what Lighthouse complains about.

So I would suggest to keep meta charset before the CSP rules. Otherwise the browser might misinterpret them.

frederikheld avatar May 07 '24 10:05 frederikheld

Thanks for this issue @frederikheld and thanks for heads up @vejja 💚

Considering that we have valid resources that have completely different approaches here, I suggest we should also support both.

So my idea would be to add an option to the ssg object that when set to true, it would add the CSP meta as the last element.

Would that make sense? I am not sure if there is one gold solution for solving both cases unless I am mistaken

Baroshem avatar May 07 '24 12:05 Baroshem

By all due respect for the security folks at Mozilla, but the Mozilla document is a tutorial with recommendations (see first paragraph) and it doesn't even say why it is recommending to put the csp meta tag before the charset meta tag against the official specs.

This has some serious Judge Dredd vibes that I often encounter in security folks: if the rules don't put us first, we change the rules to be first again.

But what are those csp rules worth if the browser can't interpret them because it uses the wrong charset?

This is what the specs say about the content security policy tag:

Authors are strongly encouraged to place meta elements as early in the document as possible, because policies in meta elements are not applied to content which precedes them. In particular, note that resources fetched or prefetched using the Link HTTP response header field, and resources fetched or prefetched using link and script elements which precede a meta-delivered policy will not be blocked.

Emphasises are mine. source, same wording for CSP2

Those two specs combined make it very clear how the order of meta tags needs to be:

1. meta charset
2. meta csp
3. everything that is script or link

If you want to introduce that switch you proposed, I strongly suggest to default to that order to be compliant to the spec and use the switch to put csp first for anyone who can sleep better if they have it that way.

frederikheld avatar May 07 '24 12:05 frederikheld

I have to agree that HTML5 is a W3C spec, while Mozilla only gives a recommendation. I’ll submit a patch

vejja avatar May 07 '24 13:05 vejja

Thanks a lot :-) I'm looking forward to it :-)

frederikheld avatar May 07 '24 14:05 frederikheld

Implementation proposal in PR #445 follows your suggestion @frederikheld

1. meta charset
2. meta csp
3. everything that is script or link

If meta charset is not the first element, then csp is first.

vejja avatar May 07 '24 16:05 vejja

Dropped #445 in favour of #449 to close this

vejja avatar May 10 '24 13:05 vejja

Thank you so much @vejja for it! We will release it as the part of RC1

Baroshem avatar May 15 '24 15:05 Baroshem