Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable String that crashes Browser

I found something very strange. When you place something like this in your html page, the browser (tested on FF and Chrome) just stops rendering the page at this place:

        <script type="text/javascript">
        // var Crash = "<!--<SCRIPT>";
        </script>

Obviously you can also do:

        <script type="text/javascript">
        var Crash = "<!--<SCRIPT>";
        </script>

Or:

        <script type="text/javascript">
         var Crash = "<!-- WHATEVER YOU WANT HERE <SCRIPT>";
        </script>

Any ideas why this happens?

like image 440
Simon Siegenthaler Avatar asked Jul 01 '16 11:07

Simon Siegenthaler


2 Answers

TL;DR:

Don't do this - it makes the parser follow some strange rules about double escaping script data, leaving it in the "wrong" state (from your point of view) by the time it gets to </script>. There are ways of escaping things in your script data to ensure it will behave as you want it to, while not breaking the parser.


The parser has a strict set of rules it follows when parsing the page. In this case:

  • We start, having seen the opening <script> tag , in the: Script data state.

  • In this stage, < triggers: Script data less-than sign state

  • then, ! triggers: Script data escape start state

  • then, - triggers: Script data escape start dash state

  • then, - triggers: Script data escaped dash dash state

  • then, < (immediately, or while in the "script data escaped state") triggers: Script data escaped less-than sign state

  • then, any a-z or A-Z (ie the "S" in "SCRIPT") get stored in the "temporary buffer", and we move to: Script data double escape start state. We stay in this state until the end of script, then > with the combination of the temporary buffer being equal to "script" triggers: Script data double escaped state

  • This just keeps emitting the characters (in your case) until we get to the < of </script>, which triggers: Script data double escaped less-than sign state

  • The / in </script> then clears the temporary buffer, and we switch to: Script data double escape end state. This again keeps appending characters to the temporary buffer, until we see the >, at which point the temporary buffer is equal to "script", which triggers us to: Script data escaped state

So we're now in a state where the browser thinks it's still within some escaped script data, rather than the original <script> tag having been closed, so any further HTML is not seen as such - it still thinks it's script data to be handed to the scripting engine rather than processed as HTML.

The reasons for the parser working this way aren't clear, but with the way things have evolved over time, it's probably because of some horrendous backwards compatibility reasons.

like image 86
James Thorpe Avatar answered Nov 01 '22 17:11

James Thorpe


In the past, it was common to handle the browsers unaware of the script tag, by adding html comments within the script blocks:

<script language="javascript">
<!--
   // code here
//-->
</script>

As you can see the first <!-- is not valid in javascript, but still the browsers have to ignore it in order to be compatible with this old trick. This seems to trigger a weird behaviour in some browser when we add a <script>, as you can see in this fiddle: https://jsfiddle.net/bjeLh5Ln/

So you need either to close the html comment by adding // --> in your script, or put </script> twice.

like image 27
Anthony Garcia-Labiad Avatar answered Nov 01 '22 18:11

Anthony Garcia-Labiad