Is there a way to pass data to the client without using inline script?
anthony-dandrea opened this issue · 5 comments
I use pretty strict CSP on some security focused sites I work on. This prevents me from using inline scripts and eval. Is there an elegant way to get APP_PROPS
passed to bundle.js on the frontend without putting inline on the page? Thank you.
There's no way to pass server-rendered props unless they're embedded somehow inline on the page (whether as a script, or embedded in HTML), or you construct some method of returning a props script that perfectly matches the route you're rendering (in which case you'd likely be setting a global variable anyway).
All JSON is escaped safely as you can see here: https://github.com/mhart/react-server-example/blob/master/server.js#L107
If you know of any other attack vectors, I'd be all ears!
You could probably embed the JSON in data attributes as well – but you'd still need to escape it and they'd be slower – plus it would still be inline. There's no way around escaping it if you're inlining it and the method I've provided here is the fastest.
So, if you wanted, you could do this in server.js
:
// ...
div({id: 'content', dangerouslySetInnerHTML: {__html:
ReactDOMServer.renderToString(App(props))
}}),
DOM.input({id: 'props', type: 'hidden', value: JSON.stringify(props)}),
script({src: '//fb.me/react-0.14.0-rc1.min.js'}),
script({src: '//fb.me/react-dom-0.14.0-rc1.min.js'}),
// ...
And then this in browser.js
:
ReactDOM.render(App(JSON.parse(document.getElementById('props').value)), document.getElementById('content'))
This will render the props inline in HTML still – and it will increase the size substantially because everything will be HTML encoded – but it's not technically a script tag anymore, so that might meet your needs.
Nice, that solution definitely works. I was hoping there was a less icky way other than just putting json somewhere other than a script tag but I can't think of another way that doesn't suck significantly more. Thank you.
Cool, np 👍