Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fizz] escape <script> textContent similar to bootstrapScript #28871

Merged
merged 1 commit into from
Apr 19, 2024

Conversation

gnoff
Copy link
Collaborator

@gnoff gnoff commented Apr 18, 2024

stacked on #28870

inline script children have been encoded as HTML for a while now but this can easily break script parsing so practically if you were rendering inline scripts you were using dangerouslySetInnerHTML. This is not great because now there is no escaping at all so you have to be even more careful. While care should always be taken when rendering untrusted script content driving users to use dangerous APIs is not the right approach and in this PR the escaping functionality used for bootstrapScripts and importMaps is being extended to any inline script.

the approach is to escape 's' or 'S" with the appropriate unicode code point if it is inside a <script or </script sequence. This has the nice benefit of minimally escaping the text for readability while still preserving full js parsing capabilities. As articulated when we introduced this escaping for prior use cases this is only safe because we are escaping the entire script content. It would be unsafe if we were not escaping the entirety of the script because we would no longer be able to ensure there are no earlier or later <script sequences that put the parser in unexpected states.

@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Apr 18, 2024
@gnoff gnoff requested a review from sebmarkbage April 18, 2024 23:48
@react-sizebot
Copy link

react-sizebot commented Apr 18, 2024

Comparing: aead514...c4e3887

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.min.js = 168.91 kB 168.91 kB = 52.93 kB 52.94 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js = 170.56 kB 170.56 kB = 53.43 kB 53.44 kB
facebook-www/ReactDOM-prod.classic.js = 590.81 kB 590.81 kB = 103.90 kB 103.90 kB
facebook-www/ReactDOM-prod.modern.js = 566.62 kB 566.62 kB = 100.09 kB 100.09 kB
test_utils/ReactAllWarnings.js Deleted 64.44 kB 0.00 kB Deleted 16.10 kB 0.00 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
test_utils/ReactAllWarnings.js Deleted 64.44 kB 0.00 kB Deleted 16.10 kB 0.00 kB

Generated by 🚫 dangerJS against c4e3887

Copy link
Collaborator

@sebmarkbage sebmarkbage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be ok, at least for modern implementations of JSON, to include a JSON.stringified variable in there which is generally the use case for an inline script.

inline script children have been encoded as HTML for a while now but this can easily break script parsing so practically if you were rendering inline scripts you were using dangerouslySetInnerHTML. This is not great because now there is no escaping at all so you have to be even more careful. While care should always be taken when rendering untrusted script content driving users to use dangerous APIs is not the right approach and in this PR the escaping functionality used for bootstrapScripts and importMaps is being extended to any inline script.

the approach is to escape 's' or 'S" with the appropriate unicode code point if it is inside a <script or </script sequence. This has the nice benefit of minimally escaping the text for readability while still preserving full js parsing capabilities. As articulated when we introduced this escaping for prior use cases this is only safe because we are escaping the entire script content. It would be unsafe if we were not escaping the entirety of the script because we would no longer be able to ensure there are no earlier or later <script sequences that put the parser in unexpected states.
@gnoff gnoff merged commit 561c023 into facebook:main Apr 19, 2024
38 checks passed
@gnoff gnoff deleted the escape-script branch April 19, 2024 00:38
github-actions bot pushed a commit that referenced this pull request Apr 19, 2024
stacked on #28870

inline script children have been encoded as HTML for a while now but
this can easily break script parsing so practically if you were
rendering inline scripts you were using dangerouslySetInnerHTML. This is
not great because now there is no escaping at all so you have to be even
more careful. While care should always be taken when rendering untrusted
script content driving users to use dangerous APIs is not the right
approach and in this PR the escaping functionality used for
bootstrapScripts and importMaps is being extended to any inline script.

the approach is to escape 's' or 'S" with the appropriate unicode code
point if it is inside a <script or </script sequence. This has the nice
benefit of minimally escaping the text for readability while still
preserving full js parsing capabilities. As articulated when we
introduced this escaping for prior use cases this is only safe because
we are escaping the entire script content. It would be unsafe if we were
not escaping the entirety of the script because we would no longer be
able to ensure there are no earlier or later <script sequences that put
the parser in unexpected states.

DiffTrain build for [561c023](561c023)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants