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:

var serverSideData = { "someKey": "someValue" };

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:

var serverSideData = { "someKey": "someValue </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:

var serverSideData = { "someKey": "someValue </script><script>alert('xss')</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 →