-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
Astro Info
Astro v5.4.2
Node v20.17.0
System Windows (x64)
Package Manager unknown
Output server
Adapter @astrojs/netlify
Integrations @astrojs/mdx
astro-icon
@astrojs/preact
@astrojs/tailwind
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
Hi, I hope this will not be a duplicate one :-)
I am working with Astro and I am very happy with it. Build a very nice site with as latest a strict required CSP with nonce value each time generated trough middleware, which also sets the required response headers. This works great with Astro and vanilla javascript because <script nonce={Astro.locals.nonce}> ... </script> makes it an inline script, also the inline <style nonce={Astro.locals.nonce}> and that is fine with me, it works as a charm.
However recently I decided that I want to make use of PREACT to make it simplified and using typescript.
But from there things went wrong, the PREACT simple component which I called with was blocked by CSP on the strict policy, (when I am developing I use a more loose policy) so I was very supprised that the strict policy blocked the PREACT component.
After the some debugging in chrome dev tools I found out that there was Astro inline client script inserted and ofcourse without nonce. So my policy works great, but what I do not understand is why the dynamically inserted client script does not have a nonce.
I read some documentation and this is normal behaviour in Astro, why ?
_Hydration Process
During the hydration process, the initial server-rendered HTML may not include a nonce because the client-side JavaScript is expected to handle the hydration without needing additional security attributes.
The hydration process is designed to seamlessly integrate client-side interactivity without altering the server-rendered content significantly._
I totally agree but on the other hand: a inserted dynamically script tag should automatically include the nonce because we have an CSP which demands it. Or am I missing something ?_
How simple could it be to get the nonce through a meta tag or somehing ?
I am using the following policy
const policy = {
"default-src": ["'self'"],
"base-uri": ["'self'"],
"frame-ancestors": ["'self'"],
"script-src": [
"'self'",
`'nonce-${nonce}'`, // Use nonce for inline scripts
"'strict-dynamic'", // Allow scripts loaded by trusted scripts
"https:", // Allow scripts from HTTPS sources
"http:", // Allow scripts from HTTP sources (consider removing for security)
],
"style-src": ["'self'", "'unsafe-inline'"], // Consider removing 'unsafe-inline' if possible
"img-src": ["'self'", "data:", "https:"],
"font-src": ["'self'", "data:", "https:"],
"frame-src": ["'self'"],
"media-src": ["'self'"],
"form-action": ["'self'"], // Prohibit clickjacking
"upgrade-insecure-requests": [], // Force HTTPS
"block-all-mixed-content": [], // Prohibit mixed content
"connect-src": [
"'self'",
"https://api.example.com", // Allow specific API calls
],
};
Hope this will bring some light ?
What's the expected result?
I expected it to work :-)
Link to Minimal Reproducible Example
Participation
- I am willing to submit a pull request for this issue.