Home Archives Search About

Cross-site Scripting </script> Vulnerability

Published January 24, 2019

Cross-site Scripting (commonly abbreviated XSS) generally boils down to never trusting user-input. If anything comes from the user, treat it as carefully as possible by never rendering it’s raw content to the DOM. With JavaScript, this generally means using .textContent (or .text() with jQuery). If there’s a templating engine (client-side or server-side), there’s generally built-in escaping for exactly this purpose.

The Problem

In most cases, the data is being displayed in some element in the <body>. However, I occasionally use a pattern of dumping data (typically JSON) from the server-side to be consumed client-side in a <script> tag:

<script>
var serverSideData = { "someKey": "someValue" };
</script>

I find this useful in scenarios where the same data is used to render the initial markup but is also used client-side to render elements dynamically. However, it has the problem of the following scenario:

<script>
var serverSideData = { "someKey": "someValue </script>" };
</script>

Browsers close <script> tags by looking for the string of characters </script> exactly, independent of the context (in this case a value of an object). This means using the same idea as SQL injection, arbitrary JavaScript can be executed in <script> tags:

<script>
var serverSideData = { "someKey": "someValue </script><script>alert('xss')</script>" };
</script>

The Solution

Since <script>s do not handle HTML entities (e.g. &lt;), all < must be replaced with \u003c. It’s important to be clear that this is not a browser bug, just something to be aware of. With that said, I hope this tidbit helps someone else out.

Last modified January 31, 2019  #dev   #security 


← Newer post  •  Older post →