-
Notifications
You must be signed in to change notification settings - Fork 214
Why is React hydration data within a script tag, commented out? #48
Comments
Some older browsers will execute any script block, even if it's type is "application/json". Best practice is to always comment it out to ensure nothing can ever execute. |
Hi @ljharb! Big thanks for the explanation! In terms of avoiding XSS, it seem that you escape |
The only thing that needs escaping is to prevent the literal string |
@ljharb there might be the chance of some white space in the In terms of performance, did you ever compare placing the JSON data inside of meta tag? the ProductHunt.com uses an alternative approach where they use an inline script to set compressed, uuencoded, likely JSON data, directly to a global variable (see image below). Possibly the data is compressed to avoid XSS. If the page data were gzipped, double compression would do little. Still, one might need to strip out the '>' before placing directly in the script tag. The web client would read the global value and then decompress and parse the JSON to an object. Did you ever try the performance of that technique? One downside I see is that until CSP 2.0 is widely supported (the nonce feature), a site that wants to use CSP would not be able to use this technique. |
CSP is very important; inline JS would be a very bad practice. Performance is irrelevant until other concerns are addressed. A meta tag would have to go in the Is there something slow about a JSON script block that warrants investigation? |
Some users of https://github.com/shakacode/react_on_rails have complained that the use of a div's meta data element to hold the JSON data is too slow. This is the source for https://nootrobox.com. There is too much quoting here. Thanks again for the advice! |
@ljharb, thank you for explanation. I have one comment:
In our testing, preliminary closing happens for everything which conforms to HTML end tag syntax (https://www.w3.org/TR/html5/syntax.html#end-tags). That means that the string can be case-insensitive and it can have spaces between That is, I guess that you are actually handling that by escaping |
script isn't self-closing, but sure, |
I was sooo not awake when I wrote this. Of course it's |
@squadette brought up the point:
@ljharb, any thoughts on if you'd need to escape double dash in the JSON? |
@justin808 that seems like a potential concern; a PR with test cases would be appreciated. However, my reading of that is that |
@ljharb no, it's not about escaping the
Here is theoretically problematic JSON content in HTML comment:
The second (inner) Both Chrome and Safari handle this correctly, and this is one of the worse parts of HTML spec (deprecated and removed in the new spec). My concern is that if we really do that comments thing due to compatibility with older/broken browsers then we should think about what other problems this approach could lead to in the same older/broken browsers. FTR: as for me, properly encoded JSON within the script tag, without comments, is perfectly ok. |
Interesting - that does sound like something we want to handle, then. |
Just in case, relevant part of HTML4 spec: https://www.w3.org/TR/html4/intro/sgmltut.html#h-3.2.4 HTML 3.2 says that it is SGML Application: https://www.w3.org/TR/REC-html32#sgml HTML 2.0: https://www.w3.org/MarkUp/html-spec/html-spec_3.html#SEC3.2.5 Sometimes they only talk about whitespace, and it's unclear what happens if there is anything else between the pairs of dash-dash. |
Here is historical evidence that this is real issue in old versions of Firefox: http://weblog.200ok.com.au/2008/01/dashing-into-trouble-why-html-comments.html |
I'm working on an issue to optimize open source library for server rendering: github.com/shakacode/react_on_rails/pull/660.
We're considering breaking away from placing react hydration data in a meta tag and moving into maybe a script tag.
Why does Airbnb puts react hydration data inside of an
<script type=“application/json” data-key=“foobar”><!--{json}--></script>
per the screen shots below? Is this related to XSS or performance reasons?view-source:https://www.airbnb.com/s/Panorama--BC--Canada?guests=10&adults=10&children=0&infants=0&checkin=12%2F18%2F2017&checkout=12%2F25%2F2017&ss_id=19nvfbwh&ss_preload=true&source=bb&page=1&s_tag=pMJm3GqR&allow_override%5B%5D=
CC: @goatslacker
The text was updated successfully, but these errors were encountered: