DOMPurify - a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. DOMPurify works with a secure default, but offers a lot of configurability and hooks. Demo:

Overview

DOMPurify

npm version Build and Test Downloads minified size gzip size dependents

NPM

DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG.

It's also very simple to use and get started with. DOMPurify was started in February 2014 and, meanwhile, has reached version 2.2.7.

DOMPurify is written in JavaScript and works in all modern browsers (Safari (10+), Opera (15+), Internet Explorer (10+), Edge, Firefox and Chrome - as well as almost anything else using Blink or WebKit). It doesn't break on MSIE6 or other legacy browsers. It either uses a fall-back or simply does nothing.

Our automated tests cover 15 different browsers right now, more to come. We also cover Node.js v14.15.1, v15.4.0, running DOMPurify on jsdom. Older Node.js versions are known to work as well.

DOMPurify is written by security people who have vast background in web attacks and XSS. Fear not. For more details please also read about our Security Goals & Threat Model. Please, read it. Like, really.

What does it do?

DOMPurify sanitizes HTML and prevents XSS attacks. You can feed DOMPurify with string full of dirty HTML and it will return a string (unless configured otherwise) with clean HTML. DOMPurify will strip out everything that contains dangerous HTML and thereby prevent XSS attacks and other nastiness. It's also damn bloody fast. We use the technologies the browser provides and turn them into an XSS filter. The faster your browser, the faster DOMPurify will be.

How do I use it?

It's easy. Just include DOMPurify on your website.

Using the unminified development version

<script type="text/javascript" src="src/purify.js"></script>

Using the minified and tested production version (source-map available)

<script type="text/javascript" src="dist/purify.min.js"></script>

Afterwards you can sanitize strings by executing the following code:

let clean = DOMPurify.sanitize( dirty );

The resulting HTML can be written into a DOM element using innerHTML or the DOM using document.write(). That is fully up to you. Note that by default, we permit HTML, SVG and MathML. If you only need HTML, which might be a very common use-case, you can easily set that up as well:

let clean = DOMPurify.sanitize( dirty , {USE_PROFILES: {html: true}} );

Is there any foot-gun potential?

Well, please note, if you first sanitize HTML and then modify it afterwards, you might easily void the effects of sanitization. If you feed the sanitized markup to another library after sanitization, please be certain that the library doesn't mess around with the HTML on its own.

Okay, makes sense, let's move on

After sanitizing your markup, you can also have a look at the property DOMPurify.removed and find out, what elements and attributes were thrown out. Please do not use this property for making any security critical decisions. This is just a little helper for curious minds.

If you're using an AMD module loader like Require.js, you can load this script asynchronously as well:

import DOMPurify from 'dompurify';

var clean = DOMPurify.sanitize(dirty);

DOMPurify also works server-side with Node.js as well as client-side via Browserify or similar translators. At least Node.js 4.x or newer is required. Our support strives to follow the Node.js release cycle. DOMPurify intends to support any version being flagged as active. At the same time we phase out support for any version flagged as maintenance. DOMPurify might not break with all versions in maintenance immediately but stops to run tests against these older versions.

npm install dompurify

For JSDOM v10 or newer

const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');

const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);

const clean = DOMPurify.sanitize(dirty);

For JSDOM versions older than v10

const createDOMPurify = require('dompurify');
const jsdom = require('jsdom').jsdom;

const window = jsdom('').defaultView;
const DOMPurify = createDOMPurify(window);

const clean = DOMPurify.sanitize(dirty);

Is there a demo?

Of course there is a demo! Play with DOMPurify

What if I find a security bug?

First of all, please immediately contact us via email so we can work on a fix. PGP key

Also, you probably qualify for a bug bounty! The fine folks over at Fastmail use DOMPurify for their services and added our library to their bug bounty scope. So, if you find a way to bypass or weaken DOMPurify, please also have a look at their website and the bug bounty info.

Some purification samples please?

How does purified markup look like? Well, the demo shows it for a big bunch of nasty elements. But let's also show some smaller examples!

DOMPurify.sanitize('<img src=x onerror=alert(1)//>'); // becomes <img src="x">
DOMPurify.sanitize('<svg><g/onload=alert(2)//<p>'); // becomes <svg><g></g></svg>
DOMPurify.sanitize('<p>abc<iframe//src=jAva&Tab;script:alert(3)>def</p>'); // becomes <p>abc</p>
DOMPurify.sanitize('<math><mi//xlink:href="data:x,<script>alert(4)</script>">'); // becomes <math><mi></mi></math>
DOMPurify.sanitize('<TABLE><tr><td>HELLO</tr></TABL>'); // becomes <table><tbody><tr><td>HELLO</td></tr></tbody></table>
DOMPurify.sanitize('<UL><li><A HREF=//google.com>click</UL>'); // becomes <ul><li><a href="//google.com">click</a></li></ul>

What is supported?

DOMPurify currently supports HTML5, SVG and MathML. DOMPurify per default allows CSS, HTML custom data attributes. DOMPurify also supports the Shadow DOM - and sanitizes DOM templates recursively. DOMPurify also allows you to sanitize HTML for being used with the jQuery $() and elm.html() API without any known problems.

What about older browsers like MSIE8?

DOMPurify offers a fall-back behavior for older MSIE browsers. It uses the MSIE-only toStaticHTML feature to sanitize. Note however that in this fall-back mode, pretty much none of the configuration flags shown below have any effect. You need to handle that yourself.

If not even toStaticHTML is supported, DOMPurify does nothing at all. It simply returns exactly the string that you fed it.

DOMPurify also exposes a property called isSupported, which tells you whether DOMPurify will be able to do its job.

What about DOMPurify and Trusted Types?

In version 1.0.9, support for Trusted Types API was added to DOMPurify. In version 2.0.0, a config flag was added to control DOMPurify's behavior regarding this.

When DOMPurify.sanitize is used in an environment where the Trusted Types API is available and RETURN_TRUSTED_TYPE is set to true, it tries to return a TrustedHTML value instead of a string (the behavior for RETURN_DOM, RETURN_DOM_FRAGMENT, and RETURN_DOM_IMPORT config options does not change).

Can I configure DOMPurify?

Yes. The included default configuration values are pretty good already - but you can of course override them. Check out the /demos folder to see a bunch of examples on how you can customize DOMPurify.

/**
 * General settings
 */

// strip {{ ... }} and <% ... %> to make output safe for template systems
// be careful please, this mode is not recommended for production usage.
// allowing template parsing in user-controlled HTML is not advised at all.
// only use this mode if there is really no alternative.
var clean = DOMPurify.sanitize(dirty, {SAFE_FOR_TEMPLATES: true});

/**
 * Control our allow-lists and block-lists
 */
// allow only <b> elements, very strict
var clean = DOMPurify.sanitize(dirty, {ALLOWED_TAGS: ['b']});

// allow only <b> and <q> with style attributes
var clean = DOMPurify.sanitize(dirty, {ALLOWED_TAGS: ['b', 'q'], ALLOWED_ATTR: ['style']});

// allow all safe HTML elements but neither SVG nor MathML
// note that the USE_PROFILES setting will override the ALLOWED_TAGS setting
// so don't use them together
var clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {html: true}});

// allow all safe SVG elements and SVG Filters, no HTML or MathML
var clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {svg: true, svgFilters: true}});

// allow all safe MathML elements and SVG, but no SVG Filters
var clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {mathMl: true, svg: true}});

// leave all safe HTML as it is and add <style> elements to block-list
var clean = DOMPurify.sanitize(dirty, {FORBID_TAGS: ['style']});

// leave all safe HTML as it is and add style attributes to block-list
var clean = DOMPurify.sanitize(dirty, {FORBID_ATTR: ['style']});

// extend the existing array of allowed tags and add <my-tag> to allow-list
var clean = DOMPurify.sanitize(dirty, {ADD_TAGS: ['my-tag']});

// extend the existing array of allowed attributes and add my-attr to allow-list
var clean = DOMPurify.sanitize(dirty, {ADD_ATTR: ['my-attr']});

// prohibit HTML5 data attributes, leave other safe HTML as is (default is true)
var clean = DOMPurify.sanitize(dirty, {ALLOW_DATA_ATTR: false});

/**
 * Control behavior relating to URI values
 */
// extend the existing array of elements that can use Data URIs
var clean = DOMPurify.sanitize(dirty, {ADD_DATA_URI_TAGS: ['a', 'area']});

// extend the existing array of elements that are safe for URI-like values (be careful, XSS risk)
var clean = DOMPurify.sanitize(dirty, {ADD_URI_SAFE_ATTR: ['my-attr']});

/**
 * Control permitted attribute values
 */
// allow external protocol handlers in URL attributes (default is false, be careful, XSS risk)
// by default only http, https, ftp, ftps, tel, mailto, callto, cid and xmpp are allowed.
var clean = DOMPurify.sanitize(dirty, {ALLOW_UNKNOWN_PROTOCOLS: true});

// allow specific protocols handlers in URL attributes via regex (default is false, be careful, XSS risk)
// by default only http, https, ftp, ftps, tel, mailto, callto, cid and xmpp are allowed.
// Default RegExp: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;
var clean = DOMPurify.sanitize(dirty, {ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|xxx):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;});

/**
 * Influence the return-type
 *
 * Careful, this setting has foot-gun potential! If you set RETURN_DOM or RETURN_DOM_FRAGMENT to true, don't set RETURN_DOM_IMPORT to false!
 * By default, our settings are secure - we believe - but returning a DOM *and* manually setting RETURN_DOM_IMPORT to false will give you XSS in some situations.
 */
// return a DOM HTMLBodyElement instead of an HTML string (default is false)
var clean = DOMPurify.sanitize(dirty, {RETURN_DOM: true});

// return a DOM DocumentFragment instead of an HTML string (default is false)
var clean = DOMPurify.sanitize(dirty, {RETURN_DOM_FRAGMENT: true});

// return a DOM DocumentFragment instead of an HTML string (default is false)
// also import it into the current document (default is false).
// RETURN_DOM_IMPORT must be set if you would like to append
// the returned node to the current document (default is true)
var clean = DOMPurify.sanitize(dirty, {RETURN_DOM_FRAGMENT: true, RETURN_DOM_IMPORT: true});
document.body.appendChild(clean);

// use the RETURN_TRUSTED_TYPE flag to turn on Trusted Types support if available
var clean = DOMPurify.sanitize(dirty, {RETURN_TRUSTED_TYPE: true}); // will return a TrustedHTML object instead of a string if possible

/**
 * Influence how we sanitize
 */
// return entire document including <html> tags (default is false)
var clean = DOMPurify.sanitize(dirty, {WHOLE_DOCUMENT: true});

// disable DOM Clobbering protection on output (default is true, handle with care, minor XSS risks here)
var clean = DOMPurify.sanitize(dirty, {SANITIZE_DOM: false});

// keep an element's content when the element is removed (default is true)
var clean = DOMPurify.sanitize(dirty, {KEEP_CONTENT: false});

// glue elements like style, script or others to document.body and prevent unintuitive browser behavior in several edge-cases (default is false)
var clean = DOMPurify.sanitize(dirty, {FORCE_BODY: true});

/**
 * Influence where we sanitize
 */
// use the IN_PLACE mode to sanitize a node "in place", which is much faster depending on how you use DOMPurify
var dirty = document.createElement('a');
dirty.setAttribute('href', 'javascript:alert(1)');
var clean = DOMPurify.sanitize(dirty, {IN_PLACE: true}); // see https://github.com/cure53/DOMPurify/issues/288 for more info

There is even more examples here, showing how you can run, customize and configure DOMPurify to fit your needs.

Persistent Configuration

Instead of repeatedly passing the same configuration to DOMPurify.sanitize, you can use the DOMPurify.setConfig method. Your configuration will persist until your next call to DOMPurify.setConfig, or until you invoke DOMPurify.clearConfig to reset it. Remember that there is only one active configuration, which means once it is set, all extra configuration parameters passed to DOMPurify.sanitize are ignored.

Hooks

DOMPurify allows you to augment its functionality by attaching one or more functions with the DOMPurify.addHook method to one of the following hooks:

  • beforeSanitizeElements
  • uponSanitizeElement (No 's' - called for every element)
  • afterSanitizeElements
  • beforeSanitizeAttributes
  • uponSanitizeAttribute
  • afterSanitizeAttributes
  • beforeSanitizeShadowDOM
  • uponSanitizeShadowNode
  • afterSanitizeShadowDOM

It passes the currently processed DOM node, when needed a literal with verified node and attribute data and the DOMPurify configuration to the callback. Check out the MentalJS hook demo to see how the API can be used nicely.

Example:

DOMPurify.addHook('beforeSanitizeElements', function (
  currentNode,
  hookEvent,
  config
) {
  // Do something with the current node and return it
  // You can also mutate hookEvent (i.e. set hookEvent.forceKeepAttr = true)
  return currentNode;
});

Continuous Integration

We are currently using Github Actions in combination with BrowserStack. This gives us the possibility to confirm for each and every commit that all is going according to plan in all supported browsers. Check out the build logs here: https://github.com/cure53/DOMPurify/actions

You can further run local tests by executing npm test. The tests work fine with Node.js v0.6.2 and [email protected].

All relevant commits will be signed with the key 0x24BB6BF4 for additional security (since 8th of April 2016).

Development and contributing

Installation (yarn i)

We support both yarn and [email protected] officially while providing lock-files for either dependency manager to provide reproducible installs and builds on either or. TravisCI itself is configured to install dependencies using yarn. When using an older version of npm we can not fully ensure the versions of installed dependencies which might lead to unanticipated problems.

Scripts

We rely on npm run-scripts for integrating with our tooling infrastructure. We use ESLint as a pre-commit hook to ensure code consistency. Moreover, to ease formatting we use prettier while building the /dist assets happens through rollup.

These are our npm scripts:

  • npm run dev to start building while watching sources for changes
  • npm run test to run our test suite via jsdom and karma
    • test:jsdom to only run tests through jsdom
    • test:karma to only run tests through karma
  • npm run lint to lint the sources using ESLint (via xo)
  • npm run format to format our sources using prettier to ease to pass ESLint
  • npm run build to build our distribution assets minified and unminified as a UMD module
    • npm run build:umd to only build an unminified UMD module
    • npm run build:umd:min to only build a minified UMD module

Note: all run scripts triggered via npm run <script> can also be started using yarn <script>.

There are more npm scripts but they are mainly to integrate with CI or are meant to be "private" for instance to amend build distribution files with every commit.

Security Mailing List

We maintain a mailing list that notifies whenever a security-critical release of DOMPurify was published. This means, if someone found a bypass and we fixed it with a release (which always happens when a bypass was found) a mail will go out to that list. This usually happens within minutes or few hours after learning about a bypass. The list can be subscribed to here:

https://lists.ruhr-uni-bochum.de/mailman/listinfo/dompurify-security

Feature releases will not be announced to this list.

Who contributed?

Many people helped and help DOMPurify become what it is and need to be acknowledged here!

granlem 💸 , oreoshake 💸 , dcramer 💸 ,tdeekens ❤️ , peernohell ❤️ , neilj, fhemberger, Joris-van-der-Wel, ydaniv, terjanq, filedescriptor, ConradIrwin, gibson042, choumx, 0xSobky, styfle, koto, tlau88, strugee, oparoz, mathiasbynens, edg2s, dnkolegov, dhardtke, wirehead, thorn0, styu, mozfreddyb, mikesamuel, jorangreef, jimmyhchan, jameydeorio, jameskraus, hyderali, hansottowirtz, hackvertor, freddyb, flavorjones, djfarrelly, devd, camerondunford, buu700, buildog, alabiaga, Vector919, Robbert, GreLI, FuzzySockets, ArtemBernatskyy, @garethheyes, @shafigullin, @mmrupp, @irsdl,ShikariSenpai, ansjdnakjdnajkd, @asutherland, @mathias, @cgvwzq, @robbertatwork, @giutro, @CmdEngineer_, @avr4mit and especially @securitymb ❤️ & @masatokinugawa ❤️

Testing powered by


And last but not least, thanks to BrowserStack Open-Source Program for supporting this project with their services for free and delivering excellent, dedicated and very professional support on top of that.

Comments
  • DOMPurify removes all custom elements

    DOMPurify removes all custom elements

    In the almost-default configuration (except RETURN_TRUSTED_TYPES: true) DOMPurify strips out all custom elements, making it unusable for custom element-based applications.

    It also removes the attribute values of is-attributes, making derived custom elements unusable.

    Here's a reproducer repo demonstrating the issue: https://github.com/franktopel/dompurify-custom-elements

    Background & Context

    Doing something as simple as document.body.innerHTML = '<foo-bar></foo-bar>'; with a default policy in place will set '' as innerHTML.

    This is my trusted-types-defining script:

    // trusted-types-policies.js
    import DOMPurify from 'dompurify';
    DOMPurify.setConfig({
      RETURN_TRUSTED_TYPE: true,
    });
    const policies = {
      createHTML: (str) => {
        return DOMPurify.sanitize(str);
      },
      createScriptURL: (str) => str,
      createScript: (str) => str,
    };
    
    if (window.trustedTypes && window.trustedTypes.createPolicy) {
      window.trustedTypes.createPolicy('default', policies);
    } 
    

    The HTML defines this Content-Security-Policy:

    <meta http-equiv="Content-Security-Policy"
        content="require-trusted-types-for 'script'; trusted-types dompurify default" />
    

    Bug

    DOMPurify removes any custom elements in the sanitized TrustedHTML.

    Input

    <foo-bar></foo-bar><div is="custom-div"></div>

    Given output

    <div is=""></div>

    Expected output

    <foo-bar></foo-bar><div is="custom-div"></div>

    Feature

    Without this, it's impossible to efficiently work with any sort of view components that import/load their HTML from a HTML file (as a string, as we won't actually have HTML imports for quite some time).

    In the current documentation, I wasn't able to find a way to configure DOMPurify to allow any custom elements. Whitelisting those tags won't work for me as the trusted types policy is implemented in the atomic web component library which is being consumed by the application, which itself is made up from composed custom elements loading HTML that includes a lot of the atomic, and even other composed custom elements.

    If whitelisting is the only option, at least that would have to allow all tags based on a pattern, like all custom elements whose tag name starts with a certain string (as well as any is-attribute values following the same pattern).

    opened by franktopel 55
  • allow arbitrary attributes and their values for configured custom elements

    allow arbitrary attributes and their values for configured custom elements

    • also added basic custom element tagname check so we don't open the floodgates with ALLOWED_CUSTOM_ELEMENTS: /script/

    This pull request fixes #601, which is a followup for #596.

    Dependencies

    If there are any dependencies on PRs or API work then list them here.

    • [x] no dependencies
    opened by franktopel 45
  • <!DOCTYPE html> is being removed when running a HTML template through dompurify

    is being removed when running a HTML template through dompurify

    This issue proposes a [bug, feature] which...

    Background & Context

    When running an HTML template through dompurify the <!DOCTYPE html> declaration at the top of the file is removed.

    e.g. https://codesandbox.io/s/quizzical-grass-cx6vj?file=/src/index.js:0-417

    import dompurify from "dompurify";
    
    const WHITELISTED_ATTR = ["content", "focusable", "nonce", "onclick"];
    const WHITELISTED_TAGS = ["link", "meta", "script", "#comment"];
    
    const config = {
      ADD_ATTR: WHITELISTED_ATTR,
      ADD_TAGS: WHITELISTED_TAGS,
      RETURN_TRUSTED_TYPE: true,
      WHOLE_DOCUMENT: true
    };
    console.log(
      dompurify
        .sanitize("<!DOCTYPE html><html><div>test</div></html>", config)
        .toString()
    );
    

    Output: <html><head></head><body><div>test</div></body></html>

    Expected output <!DOCTYPE html><html><head></head><body><div>test</div></body></html>

    opened by kohlikohl 37
  • Problem with

    Problem with "&" in the xmlns attribute

    I have the following SVG with

    <svg version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="106" height="106" viewBox="0 0 106 106" overflow="visible" enable-background="new 0 0 106 106" xml:space="preserve">

    it's transformed to

    <svg xml:space="preserve" overflow="visible" viewBox="0 0 106 106" height="106" width="106" xmlns="&amp;ns_svg;" id="Layer_1">

    Note the &amp; in the xmlns attribute.

    Is it possible to keep the ampersand without turning it into an HTML entity?

    opened by oparoz 37
  • Make DOMPurify work in Node.js

    Make DOMPurify work in Node.js

    Regarding issue #26 and #27, I originally held back Common JS style exports and publishing on npm on purpose, as DOMPurify doesn't run on a pure Node.js environment (it does client side with Browserify).

    I'm still looking for a way to get it to work on Node.js as well. jsdom lacks DOM Level 2 Traversal methods like createNodeIterator at the moment, which DOMPurify uses internally.

    What's currently missing:

    • [x] document.implementation.createHTMLDocument
      (polyfilled with return jsdom('<html><body></body></html>');)
    • [x] `window.NodeFilter (extracted the properties needed for DOMPurify from the spec)
    • [ ] document.createNodeIterator(root, whatToShow, filter, entityReferenceExpansion)
    • [ ] NodeIterator.nextNode() implementation
    • [ ] Setter method for document.body.outerHTML
    enhancement 
    opened by fhemberger 36
  • Test DOMPurify with a Browser grid

    Test DOMPurify with a Browser grid

    DOMPurify is designed to run in browsers. In ALL browsers. I would like to make some minor changes, but would like to be sure not to break anything. So I would like to have tests in a LOT of browsers in different versions and OSs. Wouldn't it be nice to have tests with a lot of browser/os combinations? There are some vendors, who offer that for free for open source projects like BrowserStack, SauceLabs or BrowserSwarm (I did not evaluate any of them for features or even fitness). I think, this test support is more important, than my suggesting changes. Are there any plans to do things like that? If not, I would like to do some research in this area.

    opened by fxa 35
  • 2.0.9 overrides adds a node binary to the PATH in npx calls

    2.0.9 overrides adds a node binary to the PATH in npx calls

    The 2.0.9 point release installs a node binary in the node_modules/.bin. In the event that your project adds node_modules/.bin to the current PATH, that node will take precedence over the system node. In my case I use npx which does this PATH management automatically.

    This is due to the commit that adds the node npm package as a dependency. Is it an absolute requirement or can it be installed as a dev dependency?

    Example of this unexpected behavior:

    ~/dev/testpackage
    ❯ npm install [email protected]
    + [email protected]
    added 1 package from 1 contributor and audited 1 package in 0.762s
    found 0 vulnerabilities
    
    
    ~/dev/testpackage took 2s
    ❯ npx node -v
    v10.18.0
    
    ~/dev/testpackage
    ❯ npm install [email protected]
    
    > [email protected] preinstall /Users/dustym/dev/testpackage/node_modules/node
    > node installArchSpecificPackage
    
    + [email protected]
    added 1 package in 5.234s
    found 0 vulnerabilities
    
    + [email protected]
    added 3 packages from 2 contributors, updated 1 package and audited 4 packages in 7.376s
    found 0 vulnerabilities
    
    
    ~/dev/testpackage took 8s
    ❯ npx node -v
    v13.13.0
    
    opened by dustym 33
  • Chrome 77: sanitize() returns TrustedHTML-Object instead of string

    Chrome 77: sanitize() returns TrustedHTML-Object instead of string

    In our usecase Chrome77 breaks our code. The sanitize method returns TrustedHTML instead of a string. We fixed it by adding a .toString() to the result of sanitize().

    Bug

    Input

    console.log(dompurify.sanitize("a"))

    Given output

    TrustedHTML-Object;

    Expected output

    "a"

    opened by Uzlopak 32
  • Node crashes on the

    Node crashes on the "import" keyword

    DOMPurify 1.0.0 is causing tests to fail across Node versions for a project I maintain. Node 4 for example fails with "SyntaxError: Unexpected reserved word" on import in src/purify.js, while Node 8 fails with "SyntaxError: Unexpected token import". Note that we're on a slightly older version of JSDOM because newer versions dropped support for Node 4 (which we still need to maintain), though I don't think that's the issue.

    https://travis-ci.org/pump-io/pump.io/jobs/264784683 is an example of a Travis job which failed because of this upgrade.

    opened by strugee 27
  • Block Network requests

    Block Network requests

    Again, not sure if this is meaningful, but does it make sense for DOMPurify to support an option where all elements that could result in network requests are removed? Just removing src, href etc attributes might be enough?

    opened by devd 27
  • DOMpurify not suitable for case-sensitive SVG

    DOMpurify not suitable for case-sensitive SVG

    DOMpurify claims to be a sanitizer for SVG but unfortunately all tags are transformed to lower case.

    After sanitizing, I get a document with all lowercase tags (unlike the original).

    SVG tags are (unlike HTML) case-sensitive and some tags like feBlend, feGaussianBlur and all other filter tags contain uppercase letters. SVG parsers don't recognize tags like <fegaussianblur>, so this causes the SVG document to render incorrectly.

    Can this behaviour please be made configurable?

    BTW, it seems that the ADD_TAGS configuration expects lowercase names as well, or they won't be accepted.

    opened by jampy 26
  • DOMPurify is not keeping h1,h2,h3 user style sheet css that is implemented in Tinymce Rich Text Editor

    DOMPurify is not keeping h1,h2,h3 user style sheet css that is implemented in Tinymce Rich Text Editor

    The rich text editor obviously has a selection between h1s, h2s, ps, tables etc. When I convert them with your package, NONE of those user style sheet css is saved. The h1's look like ordinary p tags with 0 styling. How do you fix this bug?

    opened by TimMTech 1
  • add configuration property to support custom components with no lowercase transformation

    add configuration property to support custom components with no lowercase transformation

    If you're working with React JS and you're allowing external HTML to be rendered, you need to use the dangerouselySetInnerHtml property. If this is the case and you want to support custom components in this HTML piece, you will have something like <Icon name="home"></Icon> in the HTML, and will need the JSXParser library to recognize this component and render it accordingly. Passing this HTML through the DOMPurify sanitization means that <Icon name="home"></Icon> will be transformed into <icon name="home"></icon>, which the JSXParser won't have registered and, therefore, won't be rendered.

    Background & Context

    JSX Parser library: https://www.npmjs.com/package/react-jsx-parser

    Bug

    Custom "HTML" tags names being transformed into lowercase makes DOMPurify incompatible with rendering custom React components. If I use the PARSER_MEDIA_TYPE: 'application/xhtml+xml', I get this preserved, but all links (<a href....) stripped out from the HTML, what is not desirable, and also the name space being inserted in all components as a new attribute: <Icon name="home" xmlns=\"http://www.w3.org/1999/xhtml\"></Icon>"

    Input

    <Icon name="home"></Icon>

    Given output

    <icon name="home"></icon>

    Expected output

    <Icon name="home"></Icon>

    Feature

    It would be very helpful to be able to have some configuration property like "PRESERVE_CASE", to avoid having this transformation. As an example:

    const dirty = `<div>
                                <Icon name="home" size="xl">Some text</Icon>
                                <ProgressWheel progress="75"></ProgressWheel>
                            </div>`
    const SUPPORTED_CUSTOM_COMPONENTS = ['Icon', 'ProgressWheel'];
    const SUPPORTED_CUSTOM_ATTRIBUTES = ['size', 'progress']
    const sanitizationConfig = {
    			ADD_TAGS: SUPPORTED_CUSTOM_COMPONENTS,
    			ADD_ATTR: SUPPORTED_CUSTOM_ATTRIBUTES,
                            **PRESERVE_CASE: SUPPORTED_CUSTOM_COMPONENTS**
    		};
    const clean = DOMPurify.sanitize(dirty, sanitizationConfig);
    
    opened by frandevel 14
Releases(2.4.1)
  • 2.4.1(Nov 10, 2022)

    • Added new config option ALLOWED_NAMESPACES for better XML handling, thanks @kevin-deyoungster @tosmolka
    • Added better detection of template literals when SAFE_FOR_TEMPLATES is true
    • Fixed an exception caused by DOM clobbering, thanks @masatokinugawa
    • Bumped some dependencies, thanks @marcpenya-tf
    Source code(tar.gz)
    Source code(zip)
  • 2.4.0(Aug 24, 2022)

  • 2.3.12(Aug 23, 2022)

  • 2.3.11(Aug 23, 2022)

    • Added generated type definitions for better compatibility
    • Added SANITIZE_NAMED_PROPS config option, thanks @SoheilKhodayari
    • Updated README and config documentation, thanks @0xedward
    • Updated test suite with newer Node versions
    Source code(tar.gz)
    Source code(zip)
  • 2.3.10(Jul 18, 2022)

  • 2.3.9(Jul 11, 2022)

    • Made TAG and ATTR config options case-sensitive when parsing XHTML, thanks @tosmolka
    • Bumped some dependencies, thanks @is2ei
    • Included github-actions in the dependabot config, thanks @nathannaveen
    Source code(tar.gz)
    Source code(zip)
  • 2.3.8(May 13, 2022)

    • Cleaned up a minor issue with the 2.3.7 release, thanks @johnbirds

    No other changes compared to 2.3.7 release, which entail:

    • Fixes around a bug in Safari, thanks @sybrew
    • Slightly improved performance, thanks @tiny-ben-tran
    • Lots of chores, bumps and typo fixes, thanks @is2ei
    • Removed unnecessary string trimming, thanks @christopherehlen
    Source code(tar.gz)
    Source code(zip)
  • 2.3.6(Feb 16, 2022)

    • Added an option to allow HTML5 doctypes, thanks @tosmolka
    • Bumped several dependencies, thanks @is2ei
    • Updated documentation to cover recently added flags, thanks @is2ei
    Source code(tar.gz)
    Source code(zip)
  • 2.3.5(Jan 26, 2022)

    • Performed several chores and cleanups, thanks @is2ei
    • Fixed a bug when working with Trusted Types, thanks @tosmolka
    • Fixed a bug with weird behavior on insecure nodes in IN_PLACE mode, thanks @tosmolka
    • Added more SVG attributes to allow-list, thanks @rzhade3
    Source code(tar.gz)
    Source code(zip)
  • 2.3.4(Dec 7, 2021)

    • Added support for Custom Elements, thanks @franktopel
    • Added new config settings to control Custom Element sanitizing, thanks @franktopel
    • Added faster clobber checks, thanks @GrantGryczan
    • Allow-listed SVG feImage elements, thanks @ydaniv
    • Updated test suite
    • Update supported Node versions
    • Updated README
    Source code(tar.gz)
    Source code(zip)
  • 2.3.3(Sep 20, 2021)

    • Fixed a bug in the handing of PARSER_MEDIA_TYPE spotted by @securitum-mb
    • Adjusted the tests for MSIE to make sure the results are as expected now
    Source code(tar.gz)
    Source code(zip)
  • 2.3.2(Sep 15, 2021)

  • 2.3.1(Aug 13, 2021)

    • Added code to make FORBID_CONTENTS setting configurable
    • Added role to URI-safe attributes
    • Added more paranoid handling for template elements
    Source code(tar.gz)
    Source code(zip)
  • 2.3.0(Jul 6, 2021)

    • Added better handling of document creation on Firefox
    • Added better handling of version numbers in license file
    • Added two new browser versions to test suite config
    • Fixed a bug with handling of custom data attributes
    Source code(tar.gz)
    Source code(zip)
  • 2.2.9(Jun 1, 2021)

    • Fixed some minor issues related to the NAMESPACE config
    • Fixed some minor issues relating to empty input
    • Fixed some minor issues relating to handling of invalid XML
    Source code(tar.gz)
    Source code(zip)
  • 2.2.8(Apr 28, 2021)

    • Added NAMESPACE config option, thanks @NateScarlet
    • Added better fallback for older browsers & PhantomJS, thanks @albanx
    • Extended allow-list for SVG attributes a bit
    Source code(tar.gz)
    Source code(zip)
  • 2.2.7(Mar 12, 2021)

    • Fixed handling of unsupported browsers, i.e. Safari 9 and older
    • Fixed various minor bugs and typos in README and examples
    • Added better handling of potentially harmful "is" attributes
    • Added better handling of lookupGetter functionality
    Source code(tar.gz)
    Source code(zip)
  • 2.2.6(Dec 18, 2020)

  • 2.2.4(Dec 15, 2020)

  • 2.2.3(Dec 7, 2020)

    • Fixed an mXSS issue reported by PewGrand
    • Fixed a minor issue with the license header
    • Fixed a problem with overly-eager CSS stripping
    • Updated the README and removed an XSS warning
    Source code(tar.gz)
    Source code(zip)
  • 2.2.2(Nov 2, 2020)

    • Fixed an mXSS bypass dropped on us publicly via #482
    • Fixed an mXSS variation that was reported privately short after
    • Added dialog to permitted elements list
    • Fixed a small typo in the README
    Source code(tar.gz)
    Source code(zip)
  • 2.2.0(Oct 21, 2020)

    • Fix a possible XSS in Chrome that is hidden behind #enable-experimental-web-platform-features, reported by @neilj and @mfreed7
    • Changed RETURN_DOM_IMPORT default to true to address said possible XSS
    • Updated README to reflect the new change and inform about the risks of manually setting RETURN_DOM_IMPORT back to false
    • Fixed the tests to properly address the new default
    Source code(tar.gz)
    Source code(zip)
  • 2.1.1(Sep 25, 2020)

    • Removed some code targeting old Safari versions
    • Removed some code targeting older MS Edge versions
    • Re-added some code targeting older Chrome versions, thanks @terjanq
    • Added new tests and removed unused SAFE_FOR_JQUERY test cases
    • Added Node 14.x to existing test coverage
    Source code(tar.gz)
    Source code(zip)
  • 2.1.0(Sep 23, 2020)

    • Fixed several possible mXSS patterns, thanks @hackvertor
    • Removed the SAFE_FOR_JQUERY flag (we are safe by default now for jQuery)
    • Removed several now useless mXSS checks
    • Updated the mXSS check for elements
    • Updated test cases to cover new sanitization strategy
    • Updated test website to use newer jQuery
    • Updated array of tested browsers and removed legacy browsers
    • Added "auto convert" checkbox to test website, thanks @hackvertor
    Source code(tar.gz)
    Source code(zip)
  • 2.0.17(Sep 20, 2020)

  • 2.0.16(Sep 18, 2020)

    • Fixed an mXSS-based bypass caused by nested forms inside MathML
    • Fixed a security error thrown on older Chrome on Android versions, see #470

    Credits for the bypass go to Michał Bentkowski (@securityMB) of Securitum who spotted the bug in Chrome, turned it into another DOMPurify bypass, reported and helped verifying the fix :bowing_man: :bowing_woman:

    Source code(tar.gz)
    Source code(zip)
  • 2.0.15(Sep 3, 2020)

  • 2.0.14(Aug 27, 2020)

  • 2.0.12(Jun 24, 2020)

  • 2.0.11(May 6, 2020)

Owner
Cure53
And there is fire where we walk.
Cure53
A Secure Web Proxy. Which is fast, secure, and easy to use.

Socratex A Secure Web Proxy. Which is fast, secure, and easy to use. This project is under active development. Everything may change soon. Socratex ex

Leask Wong 222 Dec 28, 2022
Sanitize untrusted HTML (to prevent XSS) with a configuration specified by a Whitelist

Sanitize untrusted HTML (to prevent XSS) with a configuration specified by a Whitelist. xss is a module used to filter input from users to prevent XSS

老雷 4.8k Jan 2, 2023
Clean up user-submitted HTML, preserving whitelisted elements and whitelisted attributes on a per-element basis. Built on htmlparser2 for speed and tolerance

sanitize-html sanitize-html provides a simple HTML sanitizer with a clear API. sanitize-html is tolerant. It is well suited for cleaning up HTML fragm

Apostrophe Technologies 3.2k Dec 26, 2022
📡 Encrypt and authenticate DevTools to use it securely remotely. Add HTTPS, and authentication to --remote-debugging-port to debug, inspect and automate from anywhere and collaborate securely on bugs.

?? Encrypt and authenticate DevTools to use it securely remotely. Add HTTPS, and authentication to --remote-debugging-port to debug, inspect and automate from anywhere and collaborate securely on bugs.

Cris 9 May 5, 2022
AnonCrypt ciphers and diciphers your messages or strings which makes you send texts to people without them understanding it.

AnonCrypt ciphers and diciphers your messages or strings which makes you send texts to people without them understanding it. Anoncrypt uses Aes192 cipher encryption type and not Hmac.

AnonyminHack5 11 Oct 23, 2022
Ganache is an Ethereum simulator that makes developing Ethereum applications faster, easier, and safer

Ganache is an Ethereum simulator that makes developing Ethereum applications faster, easier, and safer. It includes all popular RPC functions and features (like events) and can be run deterministically to make development a breeze.

Truffle Suite 2.2k Jan 7, 2023
A WebApp that allows you to follow Cryptos' News and Stats

CryptoWatch A WebApp that allows you to follow Cryptos' News and Stats. Table of Contents About The Project Screenshots Built With Getting Started Pre

null 28 Aug 4, 2022
Smart contracts for governance. Contract allows to bond custom/LP UNI-v2 tokens and get voting power

Smart contracts for governance. Contract allows to bond custom/LP UNI-v2 tokens and get voting power

Rinat Fihtengolts 3 Oct 2, 2022
A full stack digital marketplace running on Ethereum, built with Polygon, Next.js, Tailwind, Solidity, Hardhat, Ethers.js, and IPFS

A full stack digital marketplace running on Ethereum, built with Polygon, Next.js, Tailwind, Solidity, Hardhat, Ethers.js, and IPFS

Christotle Agholor 32 Dec 27, 2022
Build a Cryptocurrency Tracker with Next.js and GraphQL

Build a Cryptocurrency Tracker with Next.js and GraphQL This is the complete code to my blog post on Medium on "Build a Cryptocurrency Tracker with Ne

Presterud Myrseth Technologies 4 Dec 1, 2022
Optimized DNS/HTTP Log Tool for pentesters, faster and easy to use.

Optimized DNS/HTTP Log Tool for pentesters, faster and easy to use.

null 295 Dec 9, 2022
Policy-password is a NodeJS library written in Typescript to generate passwords according to policies and constraints.

Policy-password is a NodeJS library written in Typescript to generate passwords according to policies and constraints.

Thomas Hesse 14 May 17, 2022
A work-in-progress HTML sanitizer that strives for: performance like window.Sanitizer, readiness like DOMPurify, and ability to run in a WebWorker like neither of those.

Amuchina A work-in-progress HTML sanitizer that strives for: performance like window.Sanitizer, readiness like DOMPurify, and ability to run in a WebW

Fabio Spampinato 9 Sep 17, 2022
Secure XSS Filters.

Secure XSS Filters Just sufficient output filtering to prevent XSS! Goals More Secure. Context-dependent output filters that are developer-friendly. I

Yahoo Archive 1.1k Jan 9, 2023
A Secure Web Proxy. Which is fast, secure, and easy to use.

Socratex A Secure Web Proxy. Which is fast, secure, and easy to use. This project is under active development. Everything may change soon. Socratex ex

Leask Wong 222 Dec 28, 2022
A Secure Web Proxy. Which is fast, secure, and easy to use.

Socratex A Secure Web Proxy. Which is fast, secure, and easy to use. This project is under active development. Everything may change soon. Socratex ex

Leask Wong 220 Dec 15, 2022
An extension of DOM-testing-library to provide hooks into the shadow dom

Why? Currently, DOM-testing-library does not support checking shadow roots for elements. This can be troublesome when you're looking for something wit

Konnor Rogers 28 Dec 13, 2022
Atomico a micro-library for creating webcomponents using only functions, hooks and virtual-dom.

Atomico simplifies learning, workflow and maintenance when creating webcomponents. Scalable and reusable interfaces: with Atomico the code is simpler

Atomico 898 Dec 31, 2022
A Javascript library to export svg charts from the DOM and download them as an SVG file, PDF, or raster image (JPEG, PNG) format. Can be done all in client-side.

svg-exportJS An easy-to-use client-side Javascript library to export SVG graphics from web pages and download them as an SVG file, PDF, or raster imag

null 23 Oct 5, 2022
A JavaScript library providing multiple simultaneous, stable, fault-tolerant and resumable/restartable file uploads via the HTML5 File API.

Flow.js Flow.js is a JavaScript library providing multiple simultaneous, stable and resumable uploads via the HTML5 File API. (Demo) The library is de

HTML5 File upload 2.9k Dec 18, 2022