1 | Secure XSS Filters
|
2 | =================
|
3 | *Just sufficient* output filtering to prevent XSS!
|
4 |
|
5 | ## Goals
|
6 |
|
7 | - **More Secure.** Context-dependent output filters that are developer-friendly. It is safe to apply these filters like so:
|
8 |
|
9 | ```javascript
|
10 | el.innerHTML = "<a href=" + xssFilters.uriInUnquotedAttr(url) + ">"
|
11 | + xssFilters.uriInHTMLData(url) + "</a>";
|
12 | ```
|
13 |
|
14 | In this example, the traditional wisdom of blindly escaping the five well-known characters (`&` `<` `>` `'` `"`) would not stop XSS (e.g., when `url` is equal to `javascript:alert(1)` or ` onclick=alert(1)`).
|
15 |
|
16 | - **Just Sufficient Encoding.** Encode the *minimal* set of characters to thwart JavaScript executions, thus preventing XSS attacks while keeping most characters intact. Say goodbye to double-encoding problems such as '&amp;lt;', as often resulted by traditional filters!!
|
17 |
|
18 | ![alt Visualizing the concept of just sufficient encoding](https://ierg4210.github.io/web/images/xss-filters/xss-filters.png)
|
19 | Figure 1. "Just sufficient" encoding based on the HTML5 spec.
|
20 |
|
21 | ## Design
|
22 |
|
23 | - **Standards Compliant.** We redesign XSS filters based on the modern [HTML 5 Specification](https://html.spec.whatwg.org/multipage/syntax.html#syntax). The principle is to escape characters specific to each non-scriptable output context. Hence, untrusted inputs, once sanitized by context-sensitive escaping, cannot break out from the containing context. This approach stops malicious inputs from being executed as scripts,and also prevents the age-old problem of over/double-encoding.
|
24 | - **Carefully Designed.** Every filter is heavily scrutinized by Yahoo Security Engineers. The specific sets of characters that require encoding are minimized to preserve usability to the greatest extent possible.
|
25 |
|
26 | ## Quick Start
|
27 |
|
28 | ### Server-side (nodejs)
|
29 |
|
30 | Install the [xss-filters npm](https://www.npmjs.com/package/xss-filters), and include it as a dependency for your project.
|
31 | ```sh
|
32 | npm install xss-filters --save
|
33 | ```
|
34 |
|
35 | Require *xss-filters*, and you may use it with your favorite template engine. Or just use it directly:
|
36 |
|
37 | ```javascript
|
38 | var express = require('express');
|
39 | var app = express();
|
40 | var xssFilters = require('xss-filters');
|
41 |
|
42 | app.get('/', function(req, res){
|
43 | var firstname = req.query.firstname; //an untrusted input collected from user
|
44 | res.send('<h1> Hello, ' + xssFilters.inHTMLData(firstname) + '!</h1>');
|
45 | });
|
46 | ```
|
47 |
|
48 | ### Client-side (browser)
|
49 |
|
50 | Simply download the latest minified version from the [`dist/`](./dist) folder. Embed it in your HTML file, and all filters are available in a global object called `xssFilters`.
|
51 |
|
52 | ```html
|
53 | <script src="dist/xss-filters.min.js"></script>
|
54 | <script>
|
55 | var firstname = "..."; //an untrusted input collected from user
|
56 | document.write('<h1> Hello, ' + xssFilters.inHTMLData(firstname) + '!</h1>')
|
57 | </script>
|
58 | ```
|
59 |
|
60 | API Documentations
|
61 | -------
|
62 |
|
63 | ### WARNINGS
|
64 |
|
65 | (1) Filters **MUST ONLY** be applied to UTF-8-encoded documents.
|
66 |
|
67 | (2) **DON'T** apply any filters inside any scriptable contexts, i.e., `<script>`, `<style>`, `<embed>`, and `<svg>` tags as well as `style=""` and `onXXX=""` (e.g., `onclick`) attributes. It is **unsafe** to permit untrusted input inside a scriptable context.
|
68 |
|
69 | A workaround, if you need to include data for JS, is to use:
|
70 | ```html
|
71 | <input id="strJS" value="{{{inDoubleQuotedAttr data}}}">
|
72 | ```
|
73 | and retrieve your data with `document.getElementById('strJS').value`.
|
74 |
|
75 | ### The API
|
76 |
|
77 | There are five context-sensitive filters for generic input:
|
78 | - `<div>``{{{inHTMLData data}}}``</div>`
|
79 | - `<!--``{{{inHTMLComment comment}}}``-->`
|
80 | - `<input value='``{{{inSingleQuotedAttr value}}}``'/>`
|
81 | - `<input value="``{{{inDoubleQuotedAttr value}}}``"/>`
|
82 | - `<input value=``{{{inUnQuotedAttr value}}}``/>`
|
83 |
|
84 | > Here we use {{{ }}} to indicate output expression to ease illustrations
|
85 |
|
86 | **Whenever possible, apply the most specific filter** that describes your context and data:
|
87 |
|
88 | | Input\Context | HTMLData | HTMLComment | SingleQuotedAttr | DoubleQuotedAttr | UnQuotedAttr |
|
89 | | -------- | -------- | -------- | -------- | -------- | -------- |
|
90 | | Full URI | uriInHTMLData() | uriInHTMLComment() | uriInSingleQuotedAttr() | uriInDoubleQuotedAttr() | uriInUnQuotedAttr() |
|
91 | | URI Path | uriPathInHTMLData() | uriPathInHTMLComment() | uriPathInSingleQuotedAttr() | uriPathInDoubleQuotedAttr() | uriPathInUnQuotedAttr() |
|
92 | | URI Query | uriQueryInHTMLData() | uriQueryInHTMLComment() | uriQueryInSingleQuotedAttr() | uriQueryInDoubleQuotedAttr() | uriQueryInUnQuotedAttr() |
|
93 | | URI Component | uriComponentInHTMLData() | uriComponentInHTMLComment() | uriComponentInSingleQuotedAttr() | uriComponentInDoubleQuotedAttr() | uriComponentInUnQuotedAttr() |
|
94 | | URI Fragment | uriFragmentInHTMLData() | uriFragmentInHTMLComment() | uriFragmentInSingleQuotedAttr() | uriFragmentInDoubleQuotedAttr() | uriFragmentInUnQuotedAttr() |
|
95 |
|
96 | Check out the [documentations](../../wiki) for more details.
|
97 |
|
98 |
|
99 |
|
100 | Contributing
|
101 | -------
|
102 | To contribute, make changes in [`src/`](./src) and [`tests/`](./tests), and then do:
|
103 | ```sh
|
104 | npm test # run the tests
|
105 | npm run-script build # build the minified version for client-side use
|
106 | npm run-script docs # build the docs
|
107 | ```
|
108 |
|
109 | Build
|
110 | -----
|
111 | [![Build Status](https://travis-ci.org/yahoo/xss-filters.svg?branch=master)](https://travis-ci.org/yahoo/xss-filters)
|
112 |
|
113 | License
|
114 | -------
|
115 |
|
116 | This software is free to use under the Yahoo BSD license.
|
117 | See the [LICENSE file](./LICENSE) for license text and copyright information.
|