Escaping Javascript

Javascript string literals in HTML are subject to significant restrictions particularly due to the potential for unquoted attributes and any uncertainty as to whether Javascript will be viewed as being CDATA or PCDATA by the browser. To eliminate any possible XSS vulnerabilities, Javascript escaping for HTML extends the escaping rules of both ECMAScript and JSON to include any potentially dangerous character. Very similar to HTML attribute value escaping, this means escaping everything except basic alphanumeric characters and the comma, period and underscore characters as hexadecimal or unicode escapes.

Javascript escaping applies to all literal strings and digits. It is not possible to safely escape other Javascript markup.

To escape data in the Javascript context, use Zend\Escaper\Escaper‘s escapeJs method. An extended set of characters are escaped beyond ECMAScript’s rules for Javascript literal string escaping in order to prevent misinterpretation of Javascript as HTML leading to the injection of special characters and entities.

Examples of Bad Javascript Escaping

An example of incorrect Javascript escaping:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php header('Content-Type: application/xhtml+xml; charset=UTF-8'); ?>
<!DOCTYPE html>
<?php
$input = <<<INPUT
bar&quot;; alert(&quot;Meow!&quot;); var xss=&quot;true
INPUT;
$output = json_encode($input);
?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Unescaped Entities</title>
    <meta charset="UTF-8"/>
    <script type="text/javascript">
        <?php
        // this will result in
        // var foo = "bar&quot;; alert(&quot;Meow!&quot;); var xss=&quot;true";
        ?>
        var foo = <?php echo $output ?>;
    </script>
</head>
<body>
    <p>json_encode() is not good for escaping javascript!</p>
</body>
</html>

The above example will show an alert popup box as soon as the page is loaded, because the data is not properly escaped for the Javascript context.

Examples of Good Javascript Escaping

By using the escapeJs method in the Javascript context, such attacks can be prevented:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<!DOCTYPE html>
<?php
$input = <<<INPUT
bar&quot;; alert(&quot;Meow!&quot;); var xss=&quot;true
INPUT;
$escaper = new Zend\Escaper\Escaper('utf-8');
$output = $escaper->escapeJs($input);
?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Escaped Entities</title>
    <meta charset="UTF-8"/>
    <script type="text/javascript">
        <?php
        // this will look like
        // var foo = bar\x26quot\x3B\x3B\x20alert\x28\x26quot\x3BMeow\x21\x26quot\x3B\x29\x3B\x20var\x20xss\x3D\x26quot\x3Btrue;
        ?>
        var foo = <?php echo $output ?>;
    </script>
</head>
<body>
    <p>Zend\Escaper\Escaper::escapeJs() is good for escaping javascript!</p>
</body>
</html>

In the above example, the Javascript parser will most likely report a SyntaxError, but at least the targeted application remains safe from such attacks.

Table Of Contents

Previous topic

Escaping HTML Attributes

Next topic

Escaping Cascading Style Sheets

This Page

Note: You need to stay logged into your GitHub account to contribute to the documentation.

Edit this document

Edit this document

The source code of this file is hosted on GitHub. Everyone can update and fix errors in this document with few clicks - no downloads needed.

  1. Login with your GitHub account.
  2. Go to Escaping Javascript on GitHub.
  3. Edit file contents using GitHub's text editor in your web browser
  4. Fill in the Commit message text box at the end of the page telling why you did the changes. Press Propose file change button next to it when done.
  5. On Send a pull request page you don't need to fill in text anymore. Just press Send pull request button.
  6. Your changes are now queued for review under project's Pull requests tab on GitHub.