Live data from Hacker News

How to safely escape JSON inside HTML SCRIPT elements

sirre.al

31–40 of 47 posts

Re: How to safely escape JSON inside HTML SCRIPT elements

#31
post #8

Earlier quoted context omitted.

The other comment explains this, but I think it can also be viewed differently. It’s helpful to recognize that the inner script tags are not actual script tags. Yes, once entering a script element, the browser switches parsers and wants to skip everything until a closing script tag appears. The STYLE element, TITLE, TEXTAREA, and a few others do this. Once they chop up the HTML like this they send the contents to the…

Whoever the idiot was who came up with piling inline CSS and JS into the already heavy SGML syntax of HTML should've considered his career choices. It would've be perfectly adequate to require script and CSS to be put into external "resources" linked via src/href, especially since the spec proposals operated under the assumption there would be multiple script and styling languages going forward (like, hey, if we have…

> It would've be perfectly adequate to require script and CSS to be put into external "resources" linked via src/href

Bullshit - Navigator and IE didn't have HTTP/2. I'm guessing you didn't use dialup where your external CSS or JavaScript regularly failed to load. You didn't add extra dependencies because IE would only had two concurrent connections to load files.

It's easy to criticize past mistakes from your armchair: but I suggest you try and be a little more fair towards the people that made decisions especially when overall HTML has been a resounding success.

Re: How to safely escape JSON inside HTML SCRIPT elements

#32
post #31

Earlier quoted context omitted.

Whoever the idiot was who came up with piling inline CSS and JS into the already heavy SGML syntax of HTML should've considered his career choices. It would've be perfectly adequate to require script and CSS to be put into external "resources" linked via src/href, especially since the spec proposals operated under the assumption there would be multiple script and styling languages going forward (like, hey, if we have…

> It would've be perfectly adequate to require script and CSS to be put into external "resources" linked via src/href Bullshit - Navigator and IE didn't have HTTP/2. I'm guessing you didn't use dialup where your external CSS or JavaScript regularly failed to load. You didn't add extra dependencies because IE would only had two concurrent connections to load files. It's easy to criticize past mistakes from your armcha…

I suggest you try and check what the people you're accusing of armchair attitudes in fact were and are doing to solve problems.

Have you done even a single thing in the markup community?

Re: How to safely escape JSON inside HTML SCRIPT elements

#33
post #8

Earlier quoted context omitted.

The other comment explains this, but I think it can also be viewed differently. It’s helpful to recognize that the inner script tags are not actual script tags. Yes, once entering a script element, the browser switches parsers and wants to skip everything until a closing script tag appears. The STYLE element, TITLE, TEXTAREA, and a few others do this. Once they chop up the HTML like this they send the contents to the…

Huh, it’s still confusing to me why they would have this double-escaping behavior only inside an HTML comment. Why not have it always behave one way or the other? At what point did the parsing behavior inside and outside HTML comments split and why?

At some point I think I read a more complete justification, but I can’t find it now. There is evidence that it came about as a byproduct of the interaction of the HTML parser and JS parsers in early browsers.

In this link we can see the expectation that the HTML comment surrounds a call to document.write() which inserts a new SCRIPT element. The tags are balanced.

https://stackoverflow.com/questions/236073/why-split-the-scr...

In this HTML 4.01 spec, it’s noted to use HTML comments to hide the script contents from render, which is where we start to get the notion of using these to hide markup from display.

https://www.w3.org/TR/html401/interact/scripts.html

Some drafts of the HTML standard attempted to escape differently and didn’t have the double escape state.

https://www.w3.org/TR/2016/WD-html52-20161206/semantics-scri...

My guess is that at some point the parsers looked for balanced tags, as evidenced in the note in the last link above, but then practical issues with improperly-generated scripts led to the idea that a single SCRIPT closing tag ends the escaping. Maybe people were attempting to concatenate script contents wrong and getting stacks of opening tags that were never closed. I don’t know, but I suppose it’s recorded somewhere.

Many things in today’s HTML arose because of widespread issues with how people generated the content. The same is true of XML and XHTML by the way. Early XML mailing lists were full of people parsing XML with naive PERL regular expressions and suggesting that when someone wants to “fix” broken markup, that they do it with string-based find-and-replace.

The main difference is that the HTML spec went in the direction of saying, _if we can agree how to handle these errors then in the face of some errors we can display some content_ and we can all do it in the same way. XML is worse in some regards: certain kinds of errors are still ambiguous and up to the parser to determine how to handle, whether they are non-recoverable or recoverable. For those non-recoverable, the presence of a single error destroys the entire document, like being refused a withdrawal at the bank because you didn’t cross a 7.

At least with HTML5, it’s agreed upon what to do when errors are present and all parsers can produce the same output document; XML parsers routinely handle malformed content and do so in different ways (though most at least provide or default to a strict mode). It’s better than the early web, but not that much better.

Re: How to safely escape JSON inside HTML SCRIPT elements

#34
post #31

Earlier quoted context omitted.

> It would've be perfectly adequate to require script and CSS to be put into external "resources" linked via src/href Bullshit - Navigator and IE didn't have HTTP/2. I'm guessing you didn't use dialup where your external CSS or JavaScript regularly failed to load. You didn't add extra dependencies because IE would only had two concurrent connections to load files. It's easy to criticize past mistakes from your armcha…

I suggest you try and check what the people you're accusing of armchair attitudes in fact were and are doing to solve problems. Have you done even a single thing in the markup community?

Sorry - I shouldn't be so flippant.

Engineers hate bad compromises, and the core of engineering is making good compromises. Creating anything makes you your own critic.

Re: How to safely escape JSON inside HTML SCRIPT elements

#35
post #4
post #3

If you're evaluating JSON as JavaScript, you also need to make sure none of the objects have a key named "__proto__", or else you can end up with some strange results. (This is related to the 'prototype pollution' attack, although searching that phrase will mostly give you information about the more-dangerous variant where two objects are being merged together with some JS library. If __proto__ is just part of a lite…

But note that there's also ` ` these days (usually only useful with `id=`) ... and `importmap` I guess.

Yes, that option is the real “just do this”.

- escape `

  {{ escaped_json }}

  JSON.parse(document.getElementById('my-json').textContent)
No __proto__ issue, and no dynamic code at all, so you can use a strict CSP.

Re: How to safely escape JSON inside HTML SCRIPT elements

#36

Earlier quoted context omitted.

Why? MDN does not purport to be exhaustive, that's the spec's job.

MDN does a pretty good job anyways. Perhaps I feel that it would be in keeping with that spirit to have this condition documented. This is partly because MDN is far easier to read for the purposes of _reference_ than the spec which is easier to read for the purposes of _implementing_. It's also easier to search and to share links to, as the link you presented earlier was both wrong and confusing, and there was no nat…

Submit a change, then. MDN isn't written by some secret cabal. It's written by all of us.

Re: How to safely escape JSON inside HTML SCRIPT elements

#37
post #34

Earlier quoted context omitted.

I suggest you try and check what the people you're accusing of armchair attitudes in fact were and are doing to solve problems. Have you done even a single thing in the markup community?

Sorry - I shouldn't be so flippant. Engineers hate bad compromises, and the core of engineering is making good compromises. Creating anything makes you your own critic.

Time makes a fool of everyone.

Re: How to safely escape JSON inside HTML SCRIPT elements

#39
I would say avoid trying to understand arcane nuances better than the adversary. Assume they've simultaneously got more time on their hands and sat on the relevant standards committees. Adopt a strategy that's robust to having missed a small nuance in the standard or in the particular implementation by this or that browser. (That doesn't mean there isn't value in a blog post enumerating the edge cases, of course.)

Kaminsky described a very simple and nearly-universal technique to deal with escaping/injection issues. Encode the embedded data as base64 and decode it on the client side. This projects arbitrary data into a fixed, known domain (generally `[a-zA-Z0-9+/]*`) which you can ensure is free from control characters. (You may need to use a particular variant to achieve this, eg for URLs the last characters used are generally `-_` because both + and / are significant in that context.)

After decoding, you can pass it to JSON.parse().

Post reply on HN