GithubHelp home page GithubHelp logo

xss-filters's Introduction

Secure XSS Filters

Just sufficient output filtering to prevent XSS!

npm version dependency status Build Status

Goals

  • More Secure. Context-dependent output filters that are developer-friendly. It is safe to apply these filters like so:

    document.write("<a href=" + xssFilters.uriInUnQuotedAttr(url) + ">" + xssFilters.uriInHTMLData(url) + "</a>");

    In this example, the traditional wisdom of blindly escaping some special html entity characters (& < > ' " `) would not stop XSS (e.g., when url is equal to javascript:alert(1) or onclick=alert(1)).

  • Faster with Just Sufficient Encoding. Encode the minimal set of characters to thwart JavaScript executions, thus preventing XSS attacks while keeping most characters intact. Compared to the traditional blindly escape filter, our filters are up to two times faster, and there is no more double-encoding problems such as '&amp;lt;'!!

    alt Visualizing the concept of just sufficient encoding Figure 1. "Just sufficient" encoding based on the HTML5 spec.

Design

  • Automation. Nothing can be better than applying context-sensitive output escaping automatically. Integration with Handlebars template engine is now available. Check out express-secure-handlebars for server-side use, or secure-handlebars for client-side use.
  • Standards Compliant. The XSS filters are designed primarily based on the modern HTML 5 Specification. 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.
  • 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.

Quick Start

Server-side (nodejs)

Install the xss-filters npm, and include it as a dependency for your project.

npm install xss-filters --save

Require xss-filters, and you may use it with your favorite template engine. Or just use it directly:

var express = require('express');
var app = express();
var xssFilters = require('xss-filters');

app.get('/', function(req, res){
  var firstname = req.query.firstname; //an untrusted input collected from user
  res.send('<h1> Hello, ' + xssFilters.inHTMLData(firstname) + '!</h1>');
});

app.listen(3000);

Client-side (browser)

Simply download the latest minified version from the dist/ folder OR from the CDN. Embed it in your HTML file, and all filters are available in a global object called xssFilters.

<!doctype html><!-- You need HTML 5 mode for browser -->
...
<script src="dist/xss-filters.min.js"></script>
<script>
var firstname = "..."; //an untrusted input collected from user
document.write('<h1> Hello, ' + xssFilters.inHTMLData(firstname) + '!</h1>')
</script>

API Documentations

WARNINGS

(1) Filters MUST ONLY be applied to UTF-8-encoded documents.

(2) DON'T apply any filters inside any scriptable contexts, i.e., <script>, <style>, <object>, <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.

A workaround, if you need to include data for JS, is to use:

<input id="strJS" value="{{{inDoubleQuotedAttr data}}}">

and retrieve your data with document.getElementById('strJS').value.

The API

There are five context-sensitive filters for generic input:

  • <div> {{{inHTMLData data}}} </div>
  • <!-- {{{inHTMLComment comment}}} -->
  • <input value=' {{{inSingleQuotedAttr value}}} '/>
  • <input value=" {{{inDoubleQuotedAttr value}}} "/>
  • <input value= {{{inUnQuotedAttr value}}} />

Here we use {{{ }}} to indicate output expression to ease illustrations

Whenever possible, apply the most specific filter that describes your context and data:

Input\Context HTMLData HTMLComment SingleQuotedAttr DoubleQuotedAttr UnQuotedAttr
Full URI uriInHTMLData() uriInHTMLComment() uriInSingleQuotedAttr() uriInDoubleQuotedAttr() uriInUnQuotedAttr()
URI Path uriPathInHTMLData() uriPathInHTMLComment() uriPathInSingleQuotedAttr() uriPathInDoubleQuotedAttr() uriPathInUnQuotedAttr()
URI Query uriQueryInHTMLData() uriQueryInHTMLComment() uriQueryInSingleQuotedAttr() uriQueryInDoubleQuotedAttr() uriQueryInUnQuotedAttr()
URI Component uriComponentInHTMLData() uriComponentInHTMLComment() uriComponentInSingleQuotedAttr() uriComponentInDoubleQuotedAttr() uriComponentInUnQuotedAttr()
URI Fragment uriFragmentInHTMLData() uriFragmentInHTMLComment() uriFragmentInSingleQuotedAttr() uriFragmentInDoubleQuotedAttr() uriFragmentInUnQuotedAttr()

Check out the documentations for more details.

Contributing

To contribute, make changes in src/ and tests/, and then do:

npm test              # run the tests
npm run-script build  # build the minified version for client-side use
npm run-script docs   # build the docs

License

This software is free to use under the Yahoo BSD license. See the LICENSE file for license text and copyright information.

xss-filters's People

Contributors

adon-at-work avatar brendannee avatar davglass avatar neraliu avatar okuryu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xss-filters's Issues

Question: DON'T apply any filters inside any scriptable contexts?

I'm not sure I follow. Can you elaborate when to use the filter? I assume filter means any method in xssFilters?

  1. Is this warning only applies on Client-side?
  2. Why is the example right before the warning applying filters inside a scritable context / <script>
<script>
var firstname = "..."; //an untrusted input collected from user
document.write('<h1> Hello, ' + xssFilters.inHTMLData(firstname) + '!</h1>')
</script>

manual css style attribute filter

with the completion of the css style attribute private filter, i would like to ask for the manual css style attribute filter. the random thought would be the filter applying on the expression part of declaration and applying on the full string of css style attribute. thought?

manual js string filter

it is common for xss filters to include a filter for filtering javascript string, so we better include this in manual filter, thought?

Version mismatch in bower.json and package.json

package.json 1.1.1
bower.json 1.0.4

bower xss-filters#1.1.1 not-cached git://github.com/yahoo/xss-filters.git#1.1.1
bower xss-filters#1.1.1 resolve git://github.com/yahoo/xss-filters.git#1.1.1
bower xss-filters#1.1.1 download https://github.com/yahoo/xss-filters/archive/v1.1.1.tar.gz
bower xss-filters#1.1.1 extract archive.tar.gz
bower xss-filters#1.1.1 mismatch Version declared in the json (1.0.4) is different than the resolved one (1.1.1)
bower xss-filters#1.1.1 resolved git://github.com/yahoo/xss-filters.git#1.1.1
bower xss-filters#1.1.1 install xss-filters#1.1.1

Bypass uriInUnQuotedAttr using data: scheme.

uriInUnQuotedAttr will catch url's starting with javascript but it doesn't catch url's starting with data:text/html using FireFox this can bypass the filter.

Preview

http://127.0.0.1:3000/?url=data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5jb29raWUpPC9zY3JpcHQ%2B

Will result in:

<a href=data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5jb29raWUpPC9zY3JpcHQ+>data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5jb29raWUpPC9zY3JpcHQ+</a>

Script I used

var express = require('express');
var app = express();
var xssFilters = require('xss-filters');

app.get('/', function(req, res){
  var url = req.query.url;
  res.send("<a href=" + xssFilters.uriInUnQuotedAttr(url) + ">" + xssFilters.uriInHTMLData(url) + "</a>");
});

app.listen(3000); // <- this is not present at the readme, you might want to add it.

npm ERR! code EPROTO

Hi,
When i'm trying to install the 'xss-filters' dependency by running npm i xss-filters or npm install xss-filters (locally and globally),

I'm getting an error :

npm ERR! code EPROTO
npm ERR! errno EPROTO
npm ERR! request to https://registry.npmjs.org/xss-filters failed, reason: write EPROTO 101057795:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:openssl\ssl\s23_clnt.c:827:

with the fallowing log :

0 info it worked if it ends with ok
1 verbose cli [ 'C:\Program Files\nodejs\node.exe',
1 verbose cli 'C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js',
1 verbose cli 'i',
1 verbose cli 'xss-filters' ]
2 info using [email protected]
3 info using [email protected]
4 verbose npm-session 6337e6ced2218c84
5 silly install loadCurrentTree
6 silly install readLocalPackageData
7 silly fetchPackageMetaData error for xss-filters@latest request to https://registry.npmjs.org/xss-filters failed, reason: write EPROTO 101057795:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:openssl\ssl\s23_clnt.c:827:
8 verbose type system
9 verbose stack FetchError: request to https://registry.npmjs.org/xss-filters failed, reason: write EPROTO 101057795:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:openssl\ssl\s23_clnt.c:827:
9 verbose stack
9 verbose stack at ClientRequest.req.on.err (C:\Program Files\nodejs\node_modules\npm\node_modules\pacote\node_modules\make-fetch-happen\node_modules\node-fetch-npm\src\index.js:68:14)
9 verbose stack at emitOne (events.js:116:13)
9 verbose stack at ClientRequest.emit (events.js:211:7)
9 verbose stack at onerror (C:\Program Files\nodejs\node_modules\npm\node_modules\pacote\node_modules\make-fetch-happen\node_modules\https-proxy-agent\node_modules\agent-base\index.js:106:9)
9 verbose stack at callbackError (C:\Program Files\nodejs\node_modules\npm\node_modules\pacote\node_modules\make-fetch-happen\node_modules\https-proxy-agent\node_modules\agent-base\index.js:126:5)
9 verbose stack at
10 verbose cwd C:\Users\Dev1\Desktop\New folder
11 verbose Windows_NT 10.0.17134
12 verbose argv "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" "i" "xss-filters"
13 verbose node v8.11.1
14 verbose npm v5.6.0
15 error code EPROTO
16 error errno EPROTO
17 error request to https://registry.npmjs.org/xss-filters failed, reason: write EPROTO 101057795:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:openssl\ssl\s23_clnt.c:827:
18 verbose exit [ 1, true ]

I don't think that i'm connected by proxy because when i run this commands:
echo $http_proxy
echo $https_proxy
echo $ftp_proxy
I get an empty response.

I'm working on windows 10 environment.

null byte should be stripped?

Null byte is problematic in the HTML5 specification. I think it has no benefit having null byte allowed in any filtered output. Thoughts?

Server side usage to sanitize input

Just wondering, wouldn't you use that also on the server side as a mean to sanitize input (escape headers and other input fields)? obviously, the server can't trust the UI for doing that

Question: a basic API for most common use-case?

While I very much appreciate have dedicated API for just about every use-case scenario, this puts the burden of choosing the correct API on developers.

https://github.com/yahoo/xss-filters/wiki

It would be great have a basic API that take cares of very common use-case: let's say, an API that covers inHTMLData + inDoubleQuotedAttr.

As a follow-up question: is it ok to apply both inHTMLData + inDoubleQuotedAttr on an output? If not, then developer do really have to remember the right API.

Why is a blacklist approach taken for URI protocols, and would a whitelist be safer?

I was taking a look at version 1.2.6 and I see that the URI filters take a blacklist approach: URI_BLACKLIST_PROTOCOLS, xss-filters.js, line 59. A similar approach is taken for CSS_BLACKLIST.

What are the advantages of doing things this way? It seems to me that a whitelist is more secure by default and has the benefit of being more future-proof. The only downside that I can think of that the filter could be too strict, but that could be worked around with a default whitelist that's good enough for most use cases, plus an interface for users to add to the whitelist.

Travis build on Node 0.12 fails (timeout)

builds get stuck on the karma test

Running "karma:ci" (karma) task
No SAUCE credentials found (missing SAUCE_USERNAME and SAUCE_ACCESS_KEY env variables). Skipping SauceLabs testing.
08 06 2016 10:15:36.446:WARN [karma]: No captured browser, open http://localhost:9876/
08 06 2016 10:15:36.453:INFO [karma]: Karma v0.13.22 server started at http://localhost:9876/

Failed builds:
https://travis-ci.org/yahoo/xss-filters/jobs/79610450
https://travis-ci.org/yahoo/xss-filters/jobs/131198435

@adon-at-work

NPM error concerning shasum failure

My team and I are getting the below error when we do an npm install on our project that uses xss-filters. Not sure why this is happening, but if anyone has any insight into this, I would greatly appreciate it.

It may be worth noting that we do have a private NPM registry that has pulled this in from the public registry.

Thanks in advance for any assistance.

npm ERR! shasum check failed for /var/folders/9x/3hwlnngj0jn80b_v8bd1crh8392g3z/T/npm-82131-5d9a3836/npm.[private-npm-registry].com/xss-filters/-/xss-filters-1.2.7.tgz
npm ERR! Expected: 59fa1de201f36f2f3470dcac5f58ccc2830b0a9a
npm ERR! Actual:   e3f620eb5b3c5f82928a72c3cda91e52f55a55a7

PS: This only happens with v1.2.7

xss-filters and hmac

An interesting issue we encounter when using xss-filters is trying to get url component to stay unchanged.

Say we have an image proxy like https://github.com/atmos/camo, Which takes an url like http://example.org/<digest>?url=<image-url>, where digest is a hmac of image-url and some secret string, so that you can guarantee the url is generated by server.

Now since image-url is user input, you might want to run uriInDoubleQuotedAttr before putting it in the <img src="...">, but I tried doing that and see uriInDoubleQuotedAttr changed the component somehow.

So if we are to generate and filter a flickr image: https://farm1.staticflickr.com/1/106113_be9654002c.jpg

// before filter
https://local.dev/8ed9c616a36997f04e1fde03d7d679c684316b09/?url=https%3A%2F%2Ffarm1.staticflickr.com%2F1%2F106113_be9654002c.jpg&size=400

// after filter
https://local.dev/8ed9c616a36997f04e1fde03d7d679c684316b09/?url=https%253A%252F%252Ffarm1.staticflickr.com%252F1%252F106113_be9654002c.jpg&size=400

Should we apply the filter earlier by making uriComponentInDoubleQuotedAttr when we build the url? It does work but I am not sure if it's the safe thing to do.

PS: https://github.com/yahoo/xss-filters#warnings does the warning mean we shouldn't use this generated url in style="background-image: url(...)"?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.