Brian Silverman | 70325d6 | 2015-09-20 17:00:43 -0400 | [diff] [blame] | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
| 2 | <html> |
| 3 | <head> |
| 4 | <title>Guide to using Auto Escape</title> |
| 5 | |
| 6 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
| 7 | <link href="designstyle.css" type="text/css" rel="stylesheet"> |
| 8 | <style type="text/css"> |
| 9 | ol.bluelist li { |
| 10 | color: #3366ff; |
| 11 | font-family: sans-serif; |
| 12 | } |
| 13 | ol.bluelist li p { |
| 14 | color: #000; |
| 15 | font-family: "Times Roman", times, serif; |
| 16 | } |
| 17 | ul.blacklist li { |
| 18 | color: #000; |
| 19 | font-family: "Times Roman", times, serif; |
| 20 | } |
| 21 | </style> |
| 22 | </head> |
| 23 | <body> |
| 24 | |
| 25 | <h1><a name="Guide_Auto_Escape"></a>Guide to using Auto Escape</h1> |
| 26 | |
| 27 | <h2>Introduction</h2> |
| 28 | |
| 29 | <p>Auto Escape is an optional mode of execution in the Template System |
| 30 | developed to provide a better defense against cross-site scripting (XSS) |
| 31 | in web applications. In this mode, the Template System assumes |
| 32 | responsibility for applying the proper escaping modifiers for each |
| 33 | variable in your template (and templates it may include). As such, the |
| 34 | template developer no longer needs to manually apply escaping modifiers |
| 35 | to each variable, a process which is repetitive and error-prone |
| 36 | particularly in larger and more complex applications.</p> |
| 37 | |
| 38 | <p>In order for the Template System to properly determine the escaping |
| 39 | modifiers to apply to variables, it activates a built-in HTML-aware |
| 40 | parser during template initialization. The parser scans the template |
| 41 | to determines the context in which each variable is being emitted. |
| 42 | The scanning is performed at initialization-time only hence does not |
| 43 | contribute to processing costs at template expansion time.</p> |
| 44 | |
| 45 | <p>Refer to <a href="guide.html#security">Security Considerations</a> |
| 46 | for additional security information on escaping directives and their |
| 47 | use according to the context in which content is being expanded.</p> |
| 48 | |
| 49 | <h2>Current Status</h2> |
| 50 | |
| 51 | <p>Auto Escape currently supports well <code>HTML</code> and |
| 52 | <code>Javascript</code> templates. It also provides very basic support |
| 53 | for <code>CSS</code>, <code>JSON</code> and <code>XML</code> templates |
| 54 | where it applies the corresponding escaping modifier but without |
| 55 | utilizing a parser. We may in the future provide parsers specific |
| 56 | to these contexts and modifiers for them that are finer-grained.</p> |
| 57 | |
| 58 | <h2>Overview</h2> |
| 59 | |
| 60 | This section provides more background on Auto Escape. |
| 61 | Refer to <a href="guide.html#auto_escape">How to Auto Escape</a> |
| 62 | for information on how to leverage this mode in your application. |
| 63 | |
| 64 | <h3>Using template modifiers</h3> |
| 65 | |
| 66 | <p>In the simplest case, where you only want to use template-modifiers |
| 67 | to achieve html-safety (that is, you only use |
| 68 | <code>html_escape</code>, <code>url_query_escape</code>, and so |
| 69 | forth), you can stop specifying template-modifiers in your template at |
| 70 | all. The Auto Escape mode will generate the modifiers on its own and |
| 71 | perform the correct escaping.</p> |
| 72 | |
| 73 | <p>If you need other types of modifiers, including your own custom |
| 74 | modifiers, you can still specify them in your template and they will |
| 75 | continue to work just the same. The Auto Escape mode will simply apply |
| 76 | the appropriate escaping modifiers after your own.</p> |
| 77 | |
| 78 | <p>Other reasons for manually specifying variable modifiers include:</p> |
| 79 | <ol> |
| 80 | <li> To indicate a variable is safe. You may add the |
| 81 | <code>:none</code> modifier as the last modifier for a given |
| 82 | variable, in which case the Auto Escape mode will leave it |
| 83 | untouched and not apply escaping directives to it. Use only |
| 84 | when you are sure the variable is trusted to be safe from XSS. |
| 85 | </li> |
| 86 | |
| 87 | <li> To select a different escaping modifier from a list of |
| 88 | equivalent modifiers. Certain modifiers are equivalent from |
| 89 | an escaping point of view in that they would all ensure given |
| 90 | content is safe when escaped in a specific context. The |
| 91 | Auto Escape mode choses the most common escaping modifier for |
| 92 | that use but allows you to indicate a different choice as shown |
| 93 | below: |
| 94 | |
| 95 | <table border="1" cellpadding="3" summary="Alternatives to modifiers"> |
| 96 | <tr><th>TemplateContext</th><th>Primary Modifier</th> |
| 97 | <th>Accepted alternatives</th></tr> |
| 98 | |
| 99 | <tr> |
| 100 | <td><code>TC_HTML</code></td> |
| 101 | <td><code>:html_escape</code></td> |
| 102 | <td><ul> |
| 103 | <li><code>:pre_escape</code></li> |
| 104 | <li><code>:html_escape_with_arg=snippet</code></li> |
| 105 | <li><code>:html_escape_with_arg=attribute</code></li> |
| 106 | <li><code>:html_escape_with_arg=url</code></li> |
| 107 | <li><code>:url_query_escape</code></li> |
| 108 | <li><code>:url_escape_with_arg=html</code></li> |
| 109 | <li><code>:img_src_url_escape_with_arg=html</code></li> |
| 110 | </ul></td> |
| 111 | </tr> |
| 112 | |
| 113 | <tr> |
| 114 | <td><code>TC_HTML</code> and <code>TC_CSS</code></td> |
| 115 | <td><code>:cleanse_css</code></td> |
| 116 | <td><ul> |
| 117 | <li><code>:url_escape_with_arg=css</code></li> |
| 118 | <li><code>:img_src_url_escape_with_arg=css</code></li> |
| 119 | </ul></td> |
| 120 | </tr> |
| 121 | |
| 122 | <tr> |
| 123 | <td><code>TC_XML</code></td> |
| 124 | <td><code>:xml_escape</code></td> |
| 125 | <td><ul> |
| 126 | <li><code>:html_escape</code></li> |
| 127 | <li><code>:html_escape_with_arg=attribute</code></li> |
| 128 | </ul></td> |
| 129 | </tr> |
| 130 | |
| 131 | <tr> |
| 132 | <td><code>TC_JS</code></td> |
| 133 | <td><code>:javascript_escape</code></td> |
| 134 | <td><ul> |
| 135 | <li><code>:url_escape_with_arg=javascript</code></li> |
| 136 | <li><code>:img_src_url_escape_with_arg=javascript</code></li> |
| 137 | </ul></td> |
| 138 | </tr> |
| 139 | |
| 140 | <tr> |
| 141 | <td><code>TC_JSON</code></td> |
| 142 | <td><code>:javascript_escape</code></td> |
| 143 | <td><ul> |
| 144 | <li><code>:json_escape</code></li> |
| 145 | </ul></td> |
| 146 | </tr> |
| 147 | |
| 148 | </table></li> |
| 149 | |
| 150 | <li> To add additional escaping modifiers. The Template System will |
| 151 | never remove escaping directives you explicitly specify. </li> |
| 152 | </ol> |
| 153 | |
| 154 | <h3><A name="EscapeContext">Escaping Contexts</A> |
| 155 | </h3> |
| 156 | |
| 157 | |
| 158 | <p>The table belows indicates which modifier Auto-Escape selects to |
| 159 | escape a given variable, based on the context of the variable being |
| 160 | inserted and, possibly, on more specific information such as whether |
| 161 | the variable is inside quotation marks. The table only applies for |
| 162 | the well-supported TemplateContext values (currently |
| 163 | <code>TC_HTML</code> and <code>TC_JS</code>).</p> |
| 164 | |
| 165 | <p>In a few cases, we do not have |
| 166 | a modifier that is both safe against XSS and respecting of |
| 167 | the semantics of the variable therefore we fail the template |
| 168 | initialization. An error is logged indicating the cause of |
| 169 | the failure.</p> |
| 170 | |
| 171 | <table border="1" cellpadding="3" summary="Contexts for using modifiers"> |
| 172 | <tr bgcolor="#4169E1"> |
| 173 | <th>Context</th><th>HTML Quoted?</th> |
| 174 | <th>Examples</th><th>Action Performed</th> |
| 175 | </tr> |
| 176 | |
| 177 | <tr bgcolor="#F0F8FF"> |
| 178 | <td>Regular HTML Body and HTML comments</td><td>Any</td> |
| 179 | <td><pre><p>Hello {{USER}}</p> |
| 180 | </pre></td> |
| 181 | <td>Escape <code>USER</code> using |
| 182 | <code>:html_escape</code></td> |
| 183 | </tr> |
| 184 | |
| 185 | <tr bgcolor="#FAEBD7"> |
| 186 | <td>In URL attribute: Starts at pos 0</td><td>Yes</td> |
| 187 | <td><pre><a href="{{URL}}">;</pre></td> |
| 188 | <td>Escape <code>URL</code> using |
| 189 | <code>:url_escape_with_arg=html</code></td> |
| 190 | </tr> |
| 191 | |
| 192 | <tr bgcolor="#FAEBD7"> |
| 193 | <td>In URL attribute: Other</td><td>Yes</td> |
| 194 | <td><pre><a href="/foo?q={{QUERY}}"></pre></td> |
| 195 | <td>Escape <code>QUERY</code> using |
| 196 | <code>:html_escape</code></td> |
| 197 | </tr> |
| 198 | |
| 199 | <tr bgcolor="#FAEBD7"> |
| 200 | <td>In URL attribute: Starting at pos 0</td><td>No</td> |
| 201 | <td><pre><form action={{URL}}></pre></td> |
| 202 | <td><em>Fail template initialization</em></td> |
| 203 | </tr> |
| 204 | |
| 205 | <tr bgcolor="#FAEBD7"> |
| 206 | <td>In URL attribute: Other</td><td>No</td> |
| 207 | <td><pre><a href=/foo?q={{QUERY}}>My Link</a></pre></td> |
| 208 | <td>Escape <code>QUERY</code> using |
| 209 | <code>:url_query_escape</code></td> |
| 210 | </tr> |
| 211 | |
| 212 | <tr bgcolor="#F0F8FF"> |
| 213 | <td>In STYLE attribute</td><td>Yes</td> |
| 214 | <td><pre><div style="color:{{COLOR}};"></pre></td> |
| 215 | <td>Escape <code>COLOR</code> using |
| 216 | <code>:cleanse_css</code></td> |
| 217 | </tr> |
| 218 | |
| 219 | <tr bgcolor="#F0F8FF"> |
| 220 | <td>In STYLE attribute</td><td>No</td> |
| 221 | <td><pre><div style=color:{{COLOR}};></pre></td> |
| 222 | <td><em>Fail template initialization</em></td> |
| 223 | </tr> |
| 224 | |
| 225 | <tr bgcolor="#FAEBD7"> |
| 226 | <td>In Javascript attribute: String literal</td><td>Yes</td> |
| 227 | <td><pre><a href="url" onclick="doFoo('{{ARG}}');"></pre></td> |
| 228 | <td>Escape <code>ARG</code> using |
| 229 | <code>:javascript_escape</code></td> |
| 230 | </tr> |
| 231 | |
| 232 | <tr bgcolor="#FAEBD7"> |
| 233 | <td>In Javascript attribute: Non-string literal</td><td>Yes</td> |
| 234 | <td><pre><a href="url" onclick="doFoo({{ARG}});"></pre></td> |
| 235 | <td>Escape <code>ARG</code> using |
| 236 | <code>:javascript_escape_with_arg=number</code></td> |
| 237 | </tr> |
| 238 | |
| 239 | <tr bgcolor="#FAEBD7"> |
| 240 | <td>In Javascript attribute: Any</td><td>No</td> |
| 241 | <td><pre><a href="url" onclick=doFoo('{{ARG}}');></pre></td> |
| 242 | <td><em>Fail template initialization.</em></td> |
| 243 | </tr> |
| 244 | |
| 245 | <tr bgcolor="#F0F8FF"> |
| 246 | <td>In all other attributes</td><td>Yes</td> |
| 247 | <td><pre><b class="{{CLASS}}"></pre></td> |
| 248 | <td>Escape <code>CLASS</code> using |
| 249 | <code>:html_escape</code></td> |
| 250 | </tr> |
| 251 | |
| 252 | <tr bgcolor="#F0F8FF"> |
| 253 | <td>In all other attributes</td><td>No</td> |
| 254 | <td><pre><table border={{BORDER}}></pre></td> |
| 255 | <td>Escape <code>BORDER</code> using |
| 256 | <code>:html_escape_with_arg=attribute</code></td> |
| 257 | </tr> |
| 258 | |
| 259 | <tr bgcolor="#FAEBD7"> |
| 260 | <td>In Javascript code: In a string literal</td><td>Any</td> |
| 261 | <td><pre><script>var a = '{{VALUE}}';</script></pre></td> |
| 262 | <td>Escape <code>VALUE</code> using |
| 263 | <code>:javascript_escape</code></td> |
| 264 | </tr> |
| 265 | |
| 266 | <tr bgcolor="#FAEBD7"> |
| 267 | <td>In Javascript code: Non-string literal</td><td>Any</td> |
| 268 | <td><pre><script>var a = {{VALUE}};</script></pre></td> |
| 269 | <td>Escape <code>VALUE</code> using |
| 270 | <code>:javascript_escape_with_arg=number</code></td> |
| 271 | </tr> |
| 272 | |
| 273 | <tr bgcolor="#F0F8FF"> |
| 274 | <td>In a <style> tag</td><td>Any</td> |
| 275 | <td><pre><style>font-size={{FONTSIZE}};</style></pre></td> |
| 276 | <td>Escape <code>FONTSIZE</code> using |
| 277 | <code>:cleanse_css</code></td> |
| 278 | </tr> |
| 279 | |
| 280 | </table> |
| 281 | |
| 282 | <h4>Comments:</h4> |
| 283 | <ul> |
| 284 | <li>For values of URL-accepting attributes, we apply a different |
| 285 | modifier if the variable is at the beginning of the attribute |
| 286 | value or not because in the former case we consider the |
| 287 | variable to represent a complete URL and hence also check |
| 288 | that its scheme is safe (<code>HTTP</code> or |
| 289 | <code>HTTPS</code>).</li> |
| 290 | <li>We recommend that you enclose attribute values in quotes |
| 291 | in particular: |
| 292 | <ol> |
| 293 | <li>Under some conditions outlined in the table above, when |
| 294 | variables are present in attribute values that are not |
| 295 | enclosed in quotes, we may fail template initialization |
| 296 | because we do not have escaping modifiers that are safe to |
| 297 | use.</li> |
| 298 | <li>Also the determination of which escaping modifier |
| 299 | to apply for unquoted attribute values specifically |
| 300 | is likely to change in the future.</li> |
| 301 | </ol> |
| 302 | </ul> |
| 303 | |
| 304 | <p>The Auto Escape mode is designed to be simple to use and to produce |
| 305 | correct correct escaping with minimal input. It does however come with |
| 306 | restrictions governing the use of this template system.</p> |
| 307 | |
| 308 | <h3><a name="Limitations">Limitations</a></h3> |
| 309 | |
| 310 | <ul> |
| 311 | <li> <p>Templates may only be included in regular HTML |
| 312 | text. Including a template within HTML comments or inside an |
| 313 | HTML tag is currently not supported. In the example below, |
| 314 | <code>HEADER</code> and <code>FOOTER</code> are properly |
| 315 | included but <code>TAG</code> and <code>COMMENT</code> are |
| 316 | not.</p> |
| 317 | <pre> |
| 318 | <html><head>{{>HEADER}}</head><body> |
| 319 | <{{>TAG}}> |
| 320 | <p> |
| 321 | <!-- {{>COMMENT}} --> |
| 322 | <p>{{>FOOTER}} |
| 323 | </body></html> |
| 324 | </pre> |
| 325 | <p>If the template system detects that you are including a |
| 326 | template in another HTML context, it will log a warning.</p></li> |
| 327 | |
| 328 | <li> <p>Included templates may not cross HTML boundaries. They |
| 329 | cannot start with one <code>TemplateContext</code> and end in |
| 330 | another. For example, the template below crosses boundaries -- |
| 331 | it starts in HTML and ends in Javascript -- and is therefore |
| 332 | not a valid included template for auto-escaping.</p> |
| 333 | <pre> |
| 334 | <html> |
| 335 | <head> |
| 336 | </head> |
| 337 | <body> |
| 338 | Hello USER. |
| 339 | <script> |
| 340 | var a = 'not a nice template'; |
| 341 | </pre> |
| 342 | <p>To rectify this violation, continue the template by |
| 343 | completing the javascript code and terminating it with a |
| 344 | <code></script></code> tag.</p> </li> |
| 345 | |
| 346 | <li> <p>Error reporting. We currently report errors by logging |
| 347 | a warning or an error during initial template |
| 348 | initialization and parsing if we suspect something is |
| 349 | incorrect. Please check for them, as they indicate an error |
| 350 | that may cause auto-escaping to work improperly.</p> </li> |
| 351 | |
| 352 | <li> <p>Beware of double escaping. When you use the Auto Escape mode, |
| 353 | you surrender all variable escaping to the template system. |
| 354 | If you also perform your own escaping in your source code, you may |
| 355 | face situations where content was escaped multiple times.</p> |
| 356 | <p>In particular, do not use any of the legacy methods below or |
| 357 | others that perform variable escaping.</p> |
| 358 | <ul> |
| 359 | <li> <code>SetEscapedValue</code> </li> |
| 360 | <li> <code>SetEscapedFormatttedValue</code> </li> |
| 361 | <li> <code>SetEscapedValueAndShowSection</code> </li> |
| 362 | </ul> |
| 363 | </li> |
| 364 | |
| 365 | <li> <p>Supported HTML contexts. HTML (<code>TC_HTML</code>) and |
| 366 | Javascript (<code>TC_JS</code>) templates are well supported. |
| 367 | Other template contexts have only basic support. |
| 368 | For these contexts, variables are escaped as follows:</p> |
| 369 | <table border="1" cellpadding="3" summary="HTML contexts for modifiers"> |
| 370 | <tr><th>TemplateContext</th><th>Escaping Applied</th></tr> |
| 371 | <tr><td>TC_JSON</td> |
| 372 | <td><code>:javascript_escape</code></td></tr> |
| 373 | <tr><td>TC_XML</td> |
| 374 | <td><code>:xml_escape</code></td></tr> |
| 375 | <tr><td>TC_CSS</td> |
| 376 | <td><code>:cleanse_css</code></td></tr> |
| 377 | </table></li> |
| 378 | |
| 379 | <li> <p>New restrictions on the use of <code>BI_SPACE</code> and |
| 380 | <code>BI_NEWLINE</code>. These system variables may not be |
| 381 | re-assigned to a semantically different value via |
| 382 | <code>dict->SetValue</code> or related methods, and they may |
| 383 | not have modifiers attached to them in templates. For |
| 384 | instance: it's ok to redefine <code>BI_NEWLINE</code> from |
| 385 | <code>\n</code> to <code>\r\n</code>, since html treats them |
| 386 | identically. But changing it to <code>hello, world!</code> is |
| 387 | not allowed.</p> </li> |
| 388 | </ul> |
| 389 | |
| 390 | <h4> A new filename convention </h4> |
| 391 | |
| 392 | <p>The Auto Escape feature codifies simple conventions |
| 393 | of template filenames: </p> |
| 394 | <ol> |
| 395 | <li> CSS templates optionally include, in their filename, the |
| 396 | keywords <code>style</code> or <code>stylesheet</code> or |
| 397 | <code>css</code>. </li> |
| 398 | <li> Javascript templates optionally include, in their filename, the |
| 399 | keywords <code>js</code> or <code>javascript</code>. </li> |
| 400 | </ol> |
| 401 | |
| 402 | <p>If we find one of these keywords in the filename but |
| 403 | it does not match the template type given, we log a warning.</p> |
| 404 | |
| 405 | <hr> |
| 406 | <ul> |
| 407 | <li> <A HREF="guide.html">User's Guide</A> </li> |
| 408 | <li> <A HREF="reference.html">Reference Manual</A> </li> |
| 409 | <!-- |
| 410 | <li> <A HREF="auto_escape.html">Auto Escape</A> </li> |
| 411 | --> |
| 412 | <li> <A HREF="tips.html">Tips</A> </li> |
| 413 | <li> <A HREF="example.html">Example</A> </li> |
| 414 | </ul> |
| 415 | |
| 416 | |
| 417 | |
| 418 | <hr> |
| 419 | <address> |
| 420 | Jad Boutros<br> |
| 421 | </address> |
| 422 | |
| 423 | </body> |
| 424 | </html> |