annotate vendor/zendframework/zend-escaper/doc/book/escaping-html-attributes.md @ 7:848c88cfe644

More layout
author Chris Cannam
date Fri, 05 Jan 2018 13:59:44 +0000
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 # Escaping HTML Attributes
Chris@0 2
Chris@0 3 Escaping data in **HTML Attribute** contexts is most often done incorrectly, if
Chris@0 4 not overlooked completely by developers. Regular [HTML
Chris@0 5 escaping](escaping-html.md) can be used for escaping HTML attributes *only* if
Chris@0 6 the attribute value can be **guaranteed as being properly quoted**! To avoid
Chris@0 7 confusion, we recommend always using the HTML Attribute escaper method when
Chris@0 8 dealing with HTTP attributes specifically.
Chris@0 9
Chris@0 10 To escape data for an HTML Attribute, use `Zend\Escaper\Escaper`'s
Chris@0 11 `escapeHtmlAttr()` method. Internally it will convert the data to UTF-8, check
Chris@0 12 for its validity, and use an extended set of characters to escape that are not
Chris@0 13 covered by `htmlspecialchars()` to cover the cases where an attribute might be
Chris@0 14 unquoted or quoted illegally.
Chris@0 15
Chris@0 16 ## Examples of Bad HTML Attribute Escaping
Chris@0 17
Chris@0 18 An example of incorrect HTML attribute escaping:
Chris@0 19
Chris@0 20 ```php
Chris@0 21 <?php header('Content-Type: text/html; charset=UTF-8'); ?>
Chris@0 22 <!DOCTYPE html>
Chris@0 23 <?php
Chris@0 24 $input = <<<INPUT
Chris@0 25 ' onmouseover='alert(/ZF2!/);
Chris@0 26 INPUT;
Chris@0 27
Chris@0 28 /**
Chris@0 29 * NOTE: This is equivalent to using htmlspecialchars($input, ENT_COMPAT)
Chris@0 30 */
Chris@0 31 $output = htmlspecialchars($input);
Chris@0 32 ?>
Chris@0 33 <html>
Chris@0 34 <head>
Chris@0 35 <title>Single Quoted Attribute</title>
Chris@0 36 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Chris@0 37 </head>
Chris@0 38 <body>
Chris@0 39 <div>
Chris@0 40 <?php
Chris@0 41 // the span tag will look like:
Chris@0 42 // <span title='' onmouseover='alert(/ZF2!/);'>
Chris@0 43 ?>
Chris@0 44 <span title='<?= $output ?>'>
Chris@0 45 What framework are you using?
Chris@0 46 </span>
Chris@0 47 </div>
Chris@0 48 </body>
Chris@0 49 </html>
Chris@0 50 ```
Chris@0 51
Chris@0 52 In the above example, the default `ENT_COMPAT` flag is being used, which does
Chris@0 53 not escape single quotes, thus resulting in an alert box popping up when the
Chris@0 54 `onmouseover` event happens on the `span` element.
Chris@0 55
Chris@0 56 Another example of incorrect HTML attribute escaping can happen when unquoted
Chris@0 57 attributes are used (which is, by the way, perfectly valid HTML5):
Chris@0 58
Chris@0 59 ```php
Chris@0 60 <?php header('Content-Type: text/html; charset=UTF-8'); ?>
Chris@0 61 <!DOCTYPE html>
Chris@0 62 <?php
Chris@0 63 $input = <<<INPUT
Chris@0 64 faketitle onmouseover=alert(/ZF2!/);
Chris@0 65 INPUT;
Chris@0 66
Chris@0 67 // Tough luck using proper flags when the title attribute is unquoted!
Chris@0 68 $output = htmlspecialchars($input, ENT_QUOTES);
Chris@0 69 ?>
Chris@0 70 <html>
Chris@0 71 <head>
Chris@0 72 <title>Quoteless Attribute</title>
Chris@0 73 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Chris@0 74 </head>
Chris@0 75 <body>
Chris@0 76 <div>
Chris@0 77 <?php
Chris@0 78 // the span tag will look like:
Chris@0 79 // <span title=faketitle onmouseover=alert(/ZF2!/);>
Chris@0 80 ?>
Chris@0 81 <span title=<?= $output ?>>
Chris@0 82 What framework are you using?
Chris@0 83 </span>
Chris@0 84 </div>
Chris@0 85 </body>
Chris@0 86 </html>
Chris@0 87 ```
Chris@0 88
Chris@0 89 The above example shows how it is easy to break out from unquoted attributes in
Chris@0 90 HTML5.
Chris@0 91
Chris@0 92 ## Example of Good HTML Attribute Escaping
Chris@0 93
Chris@0 94 Both of the previous examples can be avoided by simply using the
Chris@0 95 `escapeHtmlAttr()` method:
Chris@0 96
Chris@0 97 ```php
Chris@0 98 <?php header('Content-Type: text/html; charset=UTF-8'); ?>
Chris@0 99 <!DOCTYPE html>
Chris@0 100 <?php
Chris@0 101 $input = <<<INPUT
Chris@0 102 faketitle onmouseover=alert(/ZF2!/);
Chris@0 103 INPUT;
Chris@0 104
Chris@0 105 $escaper = new Zend\Escaper\Escaper('utf-8');
Chris@0 106 $output = $escaper->escapeHtmlAttr($input);
Chris@0 107 ?>
Chris@0 108 <html>
Chris@0 109 <head>
Chris@0 110 <title>Quoteless Attribute</title>
Chris@0 111 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Chris@0 112 </head>
Chris@0 113 <body>
Chris@0 114 <div>
Chris@0 115 <?php
Chris@0 116 // the span tag will look like:
Chris@0 117 // <span title=faketitle&#x20;onmouseover&#x3D;alert&#x28;&#x2F;ZF2&#x21;&#x2F;&#x29;&#x3B;>
Chris@0 118 ?>
Chris@0 119 <span title=<?= $output ?>>
Chris@0 120 What framework are you using?
Chris@0 121 </span>
Chris@0 122 </div>
Chris@0 123 </body>
Chris@0 124 </html>
Chris@0 125 ```
Chris@0 126
Chris@0 127 In the above example, the malicious input from the attacker becomes completely
Chris@0 128 harmless as we used proper HTML attribute escaping!