The correct answer to this is "because the HTML parser in the spec says so".
From the normal "inside a script tag" state, An HTML comment start (<!--
) puts the parser into an escaped state, and from that mode a script start tag (<script>
) puts into into a double escaped state in which script closing tags (</script>
) are ignored.
Why on Earth does it do this? Backwards compatibility for inserting code into browsers that didn't support JS. Chaals gives a great answer on https://github.com/w3c/html/issues/1617, and I'll show his example of what was once normal code here:
<script>
<!-- //hide from non-JS browsers
function doSomething() {
var coolScript = "<script>" + theCodeICopied + "</script>";
document.write(coolScript);
}
// And if you forget to close your comment here, things go funnny
-->
</script>
So now we're stuck with this page-breaking vulnerability unless you escape both start AND end script tags.