sanitize-html 2.1.2 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.3.2 (2021-01-26):
4
+ - Additional fixes for iframe validation exploits. Prevent exploits based on browsers' tolerance of the use of "\" rather than "/" and the presence of whitespace at this point in the URL. Thanks to Ron Masas of [Checkmarx](https://www.checkmarx.com/) for pointing out the issue and writing unit tests.
5
+ - Documentation correction for `yarn` users. Thanks to Tagir Khadzhiev.
6
+
7
+ ## 2.3.1 (2021-01-22):
8
+ - Uses the standard WHATWG URL parser to stop IDNA (Internationalized Domain Name) attacks on the iframe hostname validator. Thanks to Ron Masas of [Checkmarx](https://www.checkmarx.com/) for pointing out the issue and suggesting the use of the WHATWG parser.
9
+
10
+ ## 2.3.0 (2020-12-16):
11
+ - Upgrades `htmlparser2` to new major version `^6.0.0`. Thanks to [Bogdan Chadkin](https://github.com/TrySound) for the contribution.
12
+
13
+ ## 2.2.0 (2020-12-02):
14
+ - Adds a note to the README about Typescript support (or the lack-thereof).
15
+ - Adds `tel` to the default `allowedSchemes`. Thanks to [Arne Herbots](https://github.com/aHerbots) for this contribution.
16
+
3
17
  ## 2.1.2 (2020-11-04):
4
18
  - Fixes typos and inconsistencies in the README. Thanks to [Eric Lefevre-Ardant](https://github.com/elefevre) for this contribution.
5
19
 
package/README.md CHANGED
@@ -24,7 +24,11 @@ HTML comments are not preserved.
24
24
 
25
25
  ## Requirements
26
26
 
27
- sanitize-html is intended for use with Node. That's pretty much it. All of its npm dependencies are pure JavaScript. sanitize-html is built on the excellent `htmlparser2` module.
27
+ sanitize-html is intended for use with Node.js and supports Node 10+. All of its npm dependencies are pure JavaScript. sanitize-html is built on the excellent `htmlparser2` module.
28
+
29
+ ### Regarding Typescript
30
+
31
+ sanitize-html is not written in Typescript and there is no plan to directly support it. There is a community supported implementation, [`@types/sanitize-html`](https://www.npmjs.com/package/@types/sanitize-html), however. Any questions or problems while using that implementation should be directed to its maintainers as directed by that project's contribution guidelines.
28
32
 
29
33
  ## How to use
30
34
 
@@ -38,7 +42,7 @@ But, perhaps you'd like to display sanitized HTML immediately in the browser for
38
42
  * Run npm install and:
39
43
 
40
44
  ```bash
41
- npm install sanitize-html # yarn install sanitize-html
45
+ npm install sanitize-html # yarn add sanitize-html
42
46
  ```
43
47
 
44
48
  The primary change in the 2.x version of sanitize-html is that it no longer includes a build that is ready for browser use. Developers are expected to include sanitize-html in their project builds (e.g., webpack) as they would any other dependency. So while sanitize-html is no longer ready to link to directly in HTML, developers can now more easily process it according to their needs.
@@ -118,7 +122,7 @@ allowedAttributes: {
118
122
  // Lots of these won't come up by default because we don't allow them
119
123
  selfClosing: [ 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta' ],
120
124
  // URL schemes we permit
121
- allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ],
125
+ allowedSchemes: [ 'http', 'https', 'ftp', 'mailto', 'tel' ],
122
126
  allowedSchemesByTag: {},
123
127
  allowedSchemesAppliedToAttributes: [ 'href', 'src', 'cite' ],
124
128
  allowProtocolRelative: true,
package/index.js CHANGED
@@ -5,7 +5,6 @@ const { isPlainObject } = require('is-plain-object');
5
5
  const deepmerge = require('deepmerge');
6
6
  const parseSrcset = require('parse-srcset');
7
7
  const { parse: postcssParse } = require('postcss');
8
- const url = require('url');
9
8
  // Tags that can conceivably represent stand-alone media.
10
9
  const mediaTags = [
11
10
  'img', 'audio', 'video', 'picture', 'svg',
@@ -109,17 +108,9 @@ function sanitizeHtml(html, options, _recursing) {
109
108
  };
110
109
  }
111
110
 
112
- if (!options) {
113
- options = sanitizeHtml.defaults;
114
- options.parser = htmlParserDefaults;
115
- } else {
116
- options = Object.assign({}, sanitizeHtml.defaults, options);
117
- if (options.parser) {
118
- options.parser = Object.assign({}, htmlParserDefaults, options.parser);
119
- } else {
120
- options.parser = htmlParserDefaults;
121
- }
122
- }
111
+ options = Object.assign({}, sanitizeHtml.defaults, options);
112
+ options.parser = Object.assign({}, htmlParserDefaults, options.parser);
113
+
123
114
  // vulnerableTags
124
115
  vulnerableTags.forEach(function (tag) {
125
116
  if (
@@ -313,12 +304,28 @@ function sanitizeHtml(html, options, _recursing) {
313
304
  if (name === 'iframe' && a === 'src') {
314
305
  let allowed = true;
315
306
  try {
307
+ // Chrome accepts \ as a substitute for / in the // at the
308
+ // start of a URL, so rewrite accordingly to prevent exploit.
309
+ // Also drop any whitespace at that point in the URL
310
+ value = value.replace(/^(\w+:)?\s*[\\/]\s*[\\/]/, '$1//');
311
+ if (value.startsWith('relative:')) {
312
+ // An attempt to exploit our workaround for base URLs being
313
+ // mandatory for relative URL validation in the WHATWG
314
+ // URL parser, reject it
315
+ throw new Error('relative: exploit attempt');
316
+ }
316
317
  // naughtyHref is in charge of whether protocol relative URLs
317
- // are cool. We should just accept them
318
- // TODO: Replace deprecated `url.parse`
319
- // eslint-disable-next-line node/no-deprecated-api
320
- parsed = url.parse(value, false, true);
321
- const isRelativeUrl = parsed && parsed.host === null && parsed.protocol === null;
318
+ // are cool. Here we are concerned just with allowed hostnames and
319
+ // whether to allow relative URLs.
320
+ //
321
+ // Build a placeholder "base URL" against which any reasonable
322
+ // relative URL may be parsed successfully
323
+ let base = 'relative://relative-site';
324
+ for (let i = 0; (i < 100); i++) {
325
+ base += `/${i}`;
326
+ }
327
+ const parsed = new URL(value, base);
328
+ const isRelativeUrl = parsed && parsed.hostname === 'relative-site' && parsed.protocol === 'relative:';
322
329
  if (isRelativeUrl) {
323
330
  // default value of allowIframeRelativeUrls is true
324
331
  // unless allowedIframeHostnames or allowedIframeDomains specified
@@ -710,7 +717,7 @@ sanitizeHtml.defaults = {
710
717
  // Lots of these won't come up by default because we don't allow them
711
718
  selfClosing: [ 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta' ],
712
719
  // URL schemes we permit
713
- allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ],
720
+ allowedSchemes: [ 'http', 'https', 'ftp', 'mailto', 'tel' ],
714
721
  allowedSchemesByTag: {},
715
722
  allowedSchemesAppliedToAttributes: [ 'href', 'src', 'cite' ],
716
723
  allowProtocolRelative: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanitize-html",
3
- "version": "2.1.2",
3
+ "version": "2.3.2",
4
4
  "description": "Clean up user-submitted HTML, preserving whitelisted elements and whitelisted attributes on a per-element basis",
5
5
  "sideEffects": false,
6
6
  "main": "index.js",
@@ -25,7 +25,7 @@
25
25
  "dependencies": {
26
26
  "deepmerge": "^4.2.2",
27
27
  "escape-string-regexp": "^4.0.0",
28
- "htmlparser2": "^4.1.0",
28
+ "htmlparser2": "^6.0.0",
29
29
  "is-plain-object": "^5.0.0",
30
30
  "klona": "^2.0.3",
31
31
  "parse-srcset": "^1.0.2",