Closed rahul37865 closed 1 year ago
Hey
Yes, the safer solution would be to use nonce like following
https://nuxt-security.vercel.app/security/headers#nonce-support
I am not sure if i am using this in a correct way I changed setting as below
security: {
headers: {
contentSecurityPolicy: {
'img-src': ["'self'", 'data:', 'http://127.0.0.1:8000'],
'script-src-attr': [ "'self'", "'nonce-{{nonce}}'","'strict-dynamic'" ]
},
strictTransportSecurity: 'max-age=0;'
},
},
Then i used useNonce() composable to get valid nonce then injected it as below
<script setup>
const nonce = useNonce()
</script>
<template>
<NuxtImg :nonce="nonce" crossorigin="anonymous" :src="postDetail.post_image" />
</template>
It doesn't resolve the error which i mentioned previously
Content-Security-Policy: The page’s settings blocked the loading of a resource at inline (“script-src-attr”).
Source: this.setAttribute('data-error', 1)
after making change it is also showing 3 warnings as below
Content-Security-Policy: Couldn’t parse invalid host 'nonce-{{nonce}}'
Content-Security-Policy: Ignoring “'self'” within script-src-attr: ‘strict-dynamic’ specified
Content-Security-Policy: Keyword ‘strict-dynamic’ within “script-src-attr” with no valid nonce or hash might block all scripts from loading
Hmm interesting.
@trijpstra-fourlights would you be up for helping with that? You have proven to be an expert in this area 😉
Pfew, a couple of things going wrong here so I'll try to explain what I think is happening!
First, an explanation on nonce:
By design, the nonce attribute is unique for every request. The middleware will regenerate the nonce and inject it in the headers.
If you are talking to an API endpoint served by your nuxt instance (e.g. /api/image/xyz), that means that without additional configuration the nonce attribute on that request will differ from the originating page, resulting in a CORS violation.
This extra configuration is (sparsely) described int he documentation
relevant part (you would want the mode: check
on the relevant API URIs):
However, looking at your OP, it seems that the API is actually served under a different URI (i.e. not by nuxt). That's why you need to add the specific URI to the img-src
allowed list. The crossorigin='anonymous'
makes sure that no cookies are sent when requesting this URI. Without this, the API would be required to set the nuxt URL as an allowed origin, otherwise you'll get CSP violations again.
So, assuming that the image is served by a different service, adding nonce makes no sense as the nonce value is not known by the API.
That leaves us only with the initial error which occurs when using NuxtImg
Content-Security-Policy: The page’s settings blocked the loading of a resource at inline (“script-src-attr”).
Source: this.setAttribute('data-error', 1)
Unfortunately, this is due to how NuxtImg
works internally. They are setting attribute at runtime (i.e. inline
) which requires you to explicitly allow that in your CSP.
Normally, your options for this are:
unsafe-inline
to script-scr-attr
(which, as you already said, opens up a security hole)NuxtImg
to be able to do this (with nonce-
)However, NuxtImg
does not currently support receiving (and propagating) a nonce
value. Thus you are (if you want to use NuxtImg
and enforce a strict CSP) limited to option 1 with all its potential security downsides.
So, as far as I can tell, the fix for this is that someone implements nonce
awareness in NuxtImg (i.e. NuxtImg
understands the nonce
prop and propagates it to the actual injected html tags).
Lastly, while it makes no sense to add the nonce (as explained above), the actual error your seeing in https://github.com/Baroshem/nuxt-security/issues/218#issuecomment-1736760193 is due to you not enabling nonce in the security settings. If you would have added nonce: true
to the security
config the error would've disappeared (but it would still not have worked due to NuxtImage
not understanding a nonce
property.
edit (1): fix formatting
edit (2): removed hash
propagation as a possible solution as it's not applicable in this case because it requires computing a hash of the offending resource and whitelisting that explicitly in your CSP config
Thanks @trijpstra-fourlights for this comprehensive explanation I raised the issue on Nuxt/Image I hope they will come up with a solution.
No problem.
I've taken a stab at the nonce
implementation for @nuxt/image
and I think it works.
You could try to use it directly, the PR branch is: https://github.com/trijpstra-fourlights/nuxt-image/tree/feat/add-nonce-support-rebased
For reference, this is the nuxt-security
config I tested it with:
security: {
nonce: true,
headers: {
contentSecurityPolicy: {
'img-src': ["'self'", 'data:', 'https:'],
'style-src': ["'self'", "'nonce-{{nonce}}'"],
'script-src': [
"'self'", // backwards compatibility for older browsers that don't support strict-dynamic
"'nonce-{{nonce}}'",
"'strict-dynamic'"
],
'script-src-attr': ["'self'", "'nonce-{{nonce}}'", "'strict-dynamic'"]
}
}
}
<template>
<NuxtImg src="https://localhost:8000/api/image/xyz" :nonce="nonce" />
</template>
<script lang="ts" setup>
const nonce = useNonce()
</script>
Great man @trijpstra-fourlights ! 🚀
Thank you so much. I am looking forward to the development of this issue / feature request :)
I have added the documentation about it https://github.com/Baroshem/nuxt-security/pull/212/commits/2f12bd61fb50f9f91a43ed8ed13453492598c745. Once it will be merged to NuxtImage I will deploy Nuxt Security docs with this instructions :)
Recently I added Nuxt Security in a Project where i am fetching data from an API URL http://127.0.0.1:8000/api/blog/post/27 While displaying image it throws error
Content-Security-Policy: The page’s settings blocked the loading of a resource at http://127.0.0.1:8000/api/blog/post_image/img12.jpg (“img-src”).
Which i fixed using below settingsand adding
crossorigin="anonymous"
in img tag<img crossorigin="anonymous" :src="postDetail.post_image" />
This fixed the issue but now i am implementing Nuxt Image Module and when i write<NuxtImg crossorigin="anonymous" :src="postDetail.post_image" />
It throws an error (only on Firefox, doesn't throw error on chrome and edge)which i fixed using below settings
My concern is, it is considered a security risk, as it can open the door to XSS attacks. It's generally recommended to avoid using 'unsafe-inline' whenever possible. Is there any other secure way to fix this error ?