This is an example of nonce hydration issues. It's as simple as possible (no build tools) to demonstrate the issue.
npm install
npm run dev
Open http://localhost:3333 in your browser and check out the console. You'll see the following error:
react-dom.development.js:73 Warning: Extra attributes from the server: nonce
at script
at body
at html
at App (http://localhost:3333/app.js:2:25)
This is resolved by passing ""
as the nonce
prop to script
tags on the
client (but not the server). This works because the browser will clear the
nonce
value automatically before any JavaScript can run (provided the nonce
value matches the CSP nonce value). So when the client hydrates, the nonce
is
empty and passing ""
for the nonce value on the client matches what the
browser did to it.
You can test this out by opening client.js
and adding nonce: ""
to the props
passed to the App component. When you do this, you'll notice the warning
disappears.
However, most people don't solve the problem this way. Instead they either use
suppressHydrationWarning
(not great because it could hide actual issues for
inline scripts especially) or they pass the nonce
value from the server to the
client. This is a really bad idea as illustrated next:
Go to http://localhost:3333/?passNonce, then you'll see the following error:
react-dom.development.js:73 Warning: Prop `nonce` did not match. Server: "" Client: "rj3157e91u"
at script
at body
at html
at App (http://localhost:3333/app.js:2:25)
This is what happens when the server render includes the data that needs to be
hydrated. Because that data often includes the nonce
attribute, the
client-render has access to it and renders the script with the nonce. This is
causes the warning and is even more problematic because it signifies a security
issue.
nonce
to prevent XSS attacksnonce
the only way it could get access is via the server rendered DOM whichnonce
.Update the error messages to explain the problem and solution.
Extra attributes from the server: nonce
error message should be updatednonce
. Maybe something like:Extra attributes from the server: nonce. The nonce attribute is a security feature and should not be passed to the client. Instead, set the nonce attribute to an empty string when client rendering.
nonce
attribute atProp nonce did not match
error message should be updated to explain thenonce
. Maybe something like:Prop nonce did not match. The nonce attribute is a security feature and should not be passed to the client as yours appears to do currently which makes your application vulnerable to cross-site scripting attacks. Instead, set the nonce attribute to an empty string when client rendering. Make certain to not send the nonce value in the DOM anywhere other than in the nonce attribute of scripts and links.