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
Preloaded Data Changes #10129
Preloaded Data Changes #10129
Conversation
@@ -108,7 +108,9 @@ | |||
</form> | |||
<% end %> | |||
|
|||
<div class="hidden" id="data-preloaded" data-preloaded="<%= preloaded_json %>"></div> | |||
<script nonce="<%= csp_nonce %>"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if you use script type="text/discourse-preload"
and JSON.parse the body instead? This avoids the HTML attribute escaping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That even bypasses the need for a nonce! Which also fixed the perf concern from @eviltrout and the nonce cache from @davidtaylorhq
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the other hand means I need to escape script close tags 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In theory, I like it. It is much simpler. However, does it make us potential victims of this slow path?
https://v8.dev/blog/cost-of-javascript-2019#json
It might be faster to emit a variable that is a JSON.parse
even though that seems counter intuitive.
@@ -19,14 +19,12 @@ export default { | |||
if (isTesting()) { | |||
return; | |||
} | |||
const preloadedDataElement = document.getElementById("data-preloaded"); | |||
const preloadedData = window.preloaded; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Premature feedback, perhaps, but we should use a much more complex variable name here to avoid conflicts since it's a global namespace.
The nonce-based CSP option is only secure if the nonce is unique on every request. I think that's mostly true with this implementation, except when the anon cache comes into play. When that happens, the same nonce will get sent to multiple clients. An attacker could then take that nonce and potentially use it to perform an XSS attack. Maybe we could use the Hash method instead? |
I am curious why we need the
But there must be a reason it was there before 🤔 |
Check if the existing Rails html escaper takes care of the angle brackets, yeah. |
There's also been some sort of performance regression since Firefox 77 relating to this data attribute https://bugzilla.mozilla.org/show_bug.cgi?id=1647942 |
@xfalcox do you think we should explore this further? Or should we close this out? |
I'm kinda with a full plate at the moment, but we should definitely follow
this up when possible. Makes our HTML payload a lot smaller, which will use
less cache, not break Firefox "View Source", etc.
…On Fri, Feb 19, 2021 at 2:53 PM David Taylor ***@***.***> wrote:
@xfalcox <https://github.com/xfalcox> do you think we should explore this
further? Or should we close this out?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#10129 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAKSH7VWASUMKEYWKKHGDH3S72QRHANCNFSM4OIXLZDA>
.
--
Rafael 'Falco' Dos Santos Silva
|
overall I support a change here if we can get it past the line, I think it probably makes sense to have a dev todo for this. will take lots of testing, maybe even we ship it behind an experimental setting for a while. |
!!! This is just a draft for discussion !!!
This draft moves the big preloaded data payload we send on the HTML from a data-attribute to a Javascript variable.
In doing this, it greatly reduces the size of the HTML (around ~50KB depending on site, before gzip) and reduces the number of necessary
JSON.parse
on the browser boot. To work with CSP it adds a nonce to secure the inline script, keeping this payload inline with the main document.On the Ruby side, we are still generating/storing JSONs everywhere, so this PR hacks around by doing parsing each part back into a Hash so it can create a proper JSON only in the last step. If this approach is deemed worth to follow up we will need to fix this by adding Hash versions of each method so we don't do double the work on the backend.
I would like the review on this refactor to see if it is something worth pursuing.
One unexpected change from this PR is that it fix the "View Source" breaking on Firefox :D . I believe the 350KB single HTML tag highlight was the culprit.