@capillarytech/cap-ui-utils 2.0.0 → 2.0.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/index.js CHANGED
@@ -8,3 +8,4 @@ export { default as validationHelper } from "./utils/validationHelper";
8
8
  export { default as loadable, FORCE_REFRESH_NOTIFIER, FORCE_REFRESH_SECONDS } from './utils/loadable';
9
9
  export { default as GTMTracker } from './utils/gtmTracker';
10
10
  export { default as compileHandlebars } from './utils/compileHandlebars';
11
+ export { default as sanitizeTemplateWithRegexp } from "./utils/contentSanitizationHelper";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capillarytech/cap-ui-utils",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Utility functions shared accross all the modules",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -12,7 +12,7 @@
12
12
  "react-ga": "^3.3.1",
13
13
  "tti-polyfill": "^0.2.2",
14
14
  "moment-timezone": "^0.5.25",
15
- "react-intl": "6.6.6",
15
+ "react-intl": "2.7.2",
16
16
  "lodash": "4.17.11",
17
17
  "handlebars": "4.0.11"
18
18
  }
@@ -0,0 +1,108 @@
1
+ // Constants used for sanitizing template content. These constants define various tags, attributes, and keywords that are considered potentially harmful in the context of an HTML template. They are used in the sanitization process to identify and remove or escape these harmful elements, helping to prevent Cross-Site Scripting (XSS) attacks.
2
+ export const TMPL_SANITIZE_FORBIDDEN_TAGS = [
3
+ "script",
4
+ "fromCharCode",
5
+ "%73%63%72%69%70%74",
6
+ "object",
7
+ "embed",
8
+ "iframe",
9
+ "frameset",
10
+ "applet",
11
+ "WBR",
12
+ "layer",
13
+ "bgsound",
14
+ "XSS",
15
+ ];
16
+ export const TMPL_SANITIZE_FORBIDDEN_ATTRS = [
17
+ "onclick",
18
+ "ondblclick",
19
+ "onmouseover",
20
+ "onmouseout",
21
+ "onkeydown",
22
+ "onkeyup",
23
+ "onkeypress",
24
+ "onfocus",
25
+ "onblur",
26
+ "onchange",
27
+ "onsubmit",
28
+ "onload",
29
+ "onerror",
30
+ "onscroll",
31
+ "onmouseup",
32
+ "onmousedown",
33
+ "onselect",
34
+ "onplay",
35
+ "onmousemove",
36
+ "onwheel",
37
+ "oninput",
38
+ "oncopy",
39
+ "oncut",
40
+ "onpaste",
41
+ "oncontextmenu",
42
+ "ondrag",
43
+ "ondragend",
44
+ "ondragenter",
45
+ "ondragleave",
46
+ "ondragover",
47
+ "ondragstart",
48
+ "ondrop",
49
+ "onabort",
50
+ "oncanplay",
51
+ "oncanplaythrough",
52
+ "oncuechange",
53
+ "ondurationchange",
54
+ "onemptied",
55
+ "onended",
56
+ "onloadeddata",
57
+ "onloadedmetadata",
58
+ "onloadstart",
59
+ "onpause",
60
+ "onplaying",
61
+ "onprogress",
62
+ "onratechange",
63
+ "onseeked",
64
+ "onseeking",
65
+ "onstalled",
66
+ "onsuspend",
67
+ "ontimeupdate",
68
+ "onvolumechange",
69
+ "onwaiting",
70
+ "onreset",
71
+ "onunload",
72
+ "onresize",
73
+ "ontoggle",
74
+ "onshow",
75
+ "onmousewheel",
76
+ "onsearch",
77
+ "oninvalid",
78
+ "onstorage",
79
+ "onpopstate",
80
+ "onpageshow",
81
+ "onpagehide",
82
+ "onoffline",
83
+ "ononline",
84
+ "onmessage",
85
+ "onhashchange",
86
+ "onbeforeunload",
87
+ "onbeforeprint",
88
+ "onafterprint",
89
+ "onmouseleave",
90
+ "onmouseenter",
91
+ "onstart",
92
+ "onbeforeload",
93
+ "onfilterchange",
94
+ "onbegin",
95
+ "onReadyStateChange",
96
+ "onPropertyChange",
97
+ "onend",
98
+ ];
99
+ export const TMPL_SANITIZE_FORBIDDEN_JS_TAGS = [
100
+ "javascript:",
101
+ "javascript#",
102
+ "javascript:",
103
+ "javascriptalert",
104
+ "jscript",
105
+ "vbscript:",
106
+ "livescript:",
107
+ "xss:",
108
+ ];
@@ -0,0 +1,111 @@
1
+ import {
2
+ TMPL_SANITIZE_FORBIDDEN_TAGS,
3
+ TMPL_SANITIZE_FORBIDDEN_ATTRS,
4
+ TMPL_SANITIZE_FORBIDDEN_JS_TAGS,
5
+ } from "./constants";
6
+
7
+ /**
8
+ * Sanitizes the given content by removing forbidden HTML tags, attributes, and JavaScript code.
9
+ *
10
+ * @param {string} content - The content to be sanitized.
11
+ * @returns {string} The sanitized content.
12
+ */
13
+ const sanitizeTemplateWithRegexp = (content) => {
14
+ try {
15
+ const tagsJoined = TMPL_SANITIZE_FORBIDDEN_TAGS.join("|");
16
+ const attrsJoined = TMPL_SANITIZE_FORBIDDEN_ATTRS.join("|");
17
+ const jsKeywordsJoined = TMPL_SANITIZE_FORBIDDEN_JS_TAGS.join("|");
18
+
19
+ // Full tag regex: Matches complete HTML tags including their content for specified forbidden tags.
20
+ const fullTagRegex = new RegExp(
21
+ `<(${tagsJoined})\\b[^<]*(?:(?!<\/(${tagsJoined})>)<[^<]*)*<\/(${tagsJoined})>`,
22
+ "gi"
23
+ );
24
+ // Empty tag regex: Matches empty or self-closing instances of specified forbidden tags.
25
+ const emptyTagRegex = new RegExp(`<(${tagsJoined}).*\/?>`, "gi");
26
+ // Attribute regex: Matches forbidden attributes that can execute JavaScript or other actions.
27
+ const attrRegex = new RegExp(
28
+ `\\b(${attrsJoined})\\s*=\\s*((["'])(?:\\\\|\\.|[^\\"])*\\x03|&quot;(?:\\\\|\\.|[^\\&quot;])*&quot;|[^ >]*?)(?=\s*(?:\/?>|\/?&gt;))`,
29
+ "gi"
30
+ );
31
+ // Href with JavaScript regex: Matches 'href' and other js attributes that initiate with JavaScript or other harmful protocols.
32
+ const hrefJavaScriptRegex = new RegExp(
33
+ `href\\s*=\\s*(["\'])(?:\\*?.)*?(?:\\?\\")?(${jsKeywordsJoined})(?:\\\\?.)*?\\1`,
34
+ "gi"
35
+ );
36
+ // Href in JSON format for BEE editor: Specifically designed to match 'href' attributes within JSON strings that contain harmful JavaScript.
37
+ const hrefRegexForJsonString = new RegExp(
38
+ `href=\\\\["\'](${jsKeywordsJoined}).*?\\\\["\']`,
39
+ "gi"
40
+ );
41
+ // Encoded script tag regex: Matches script tags that are HTML entity encoded.
42
+ const encodedScriptTagRegex = new RegExp(
43
+ `(?:<(${tagsJoined})|&lt;(${tagsJoined})|&amp;lt;(${tagsJoined}))(.*?)(?:<\/(${tagsJoined})>|&lt;\/(${tagsJoined})>|\/>|\/(${tagsJoined})&gt;|\/&gt;|\/(${tagsJoined})&amp;gt;|\/(${tagsJoined}) --&gt;)`,
44
+ "gi"
45
+ );
46
+ // Src with JavaScript regex: Matches 'src' attributes that begin with JavaScript or other harmful protocols.
47
+ const srcWithJavaScriptRegex = new RegExp(
48
+ `src\\s*=\\s*(?:'|"|&quot;)?\\s*(${jsKeywordsJoined})[^\\s>]*(?=\\s*(>|\/>|&gt;|\/&gt;))`,
49
+ "gi"
50
+ );
51
+ // Unicode regex: Matches Unicode entities within the content.
52
+ const regexForUnicode = new RegExp(
53
+ "&#\\d+;|&#0*[0-9]+;|&#x[0-9a-zA-Z]+;|\\\\00[0-9a-zA-Z]{2,}",
54
+ "gi"
55
+ );
56
+ // Global JavaScript regex: Matches instances of JavaScript protocol globally.
57
+ const globalJavascriptRegex = new RegExp(
58
+ `(${jsKeywordsJoined})[^;"'>)]*([;"'>)]|\/>)`,
59
+ "gi"
60
+ );
61
+ // Style import regex: Matches '@import' used within <style> tags that might import harmful stylesheets.
62
+ const styleImportRegex = new RegExp(`@import[^<]*?(?=(<|&lt;|\/>))`, "gi");
63
+ // JavaScript built-in functions regex: Matches calls to 'alert', 'prompt', or 'confirm' that could be used for XSS.
64
+ const jsBuiltInFunctionRegex = new RegExp(
65
+ `\\b(alert|prompt|confirm)\\s*(\\(|&lpar;|&amp;lpar;)[^)]*(\\)|&rpar;|&amp;rpar;)`,
66
+ "gi"
67
+ );
68
+ // Hexadecimal code regex: Matches all hexadecimal HTML entities.
69
+ const hexCodeRegex = new RegExp(`((&|&amp;)#[xX]?[0-9a-fA-F]+;?)`, "gi");
70
+ // Immediate unclosed tag regex: Matches tags that are not properly closed and have URI encoded script tag.
71
+ const immediateUnclosedTagRegex = new RegExp(
72
+ `(?:<|&lt;|&amp;lt;|%3C)\\s*(${tagsJoined})\\b.*?(?:>|&gt;|&amp;gt;|%3E)([\\s\\S]*?)(?:<|&lt;|&amp;lt;|%3C)(\\/|%2F)\\s*(${tagsJoined})\\b.*?(?:>|&gt;|&amp;gt;|%3E)`,
73
+ "gi"
74
+ );
75
+ // Eval regex: Matches dangerous 'eval()' usage that could execute arbitrary JavaScript.
76
+ const evalRegex = new RegExp(
77
+ "[-\\/]?\\beval\\(([^)]|\\\\.|&\\w+;)+\\)[-\\/]?",
78
+ "gi"
79
+ );
80
+ const unclosedOrSelfClosedTagRegex = new RegExp(
81
+ `(?:<|&lt;|&amp;lt;|amp;lt;)\\s*(${tagsJoined})\\b[\\s\\S]*?(?:\/>|>|&gt;|\/&gt;|&amp;gt;|amp;gt;|\/&amp;gt;|\\Z)`,
82
+ "gi"
83
+ );
84
+ // regex to replace the &#39 (ascii html for apostrophe) to the apostrophe for ckeditor content
85
+ const apostropheRegex = new RegExp('&#39;', 'gi');
86
+
87
+ content = content
88
+ .replaceAll(apostropheRegex, '\'')
89
+ .replace(hexCodeRegex, "")
90
+ .replace(encodedScriptTagRegex, "")
91
+ .replace(fullTagRegex, "")
92
+ .replace(emptyTagRegex, "")
93
+ .replace(immediateUnclosedTagRegex, "")
94
+ .replace(attrRegex, "")
95
+ .replace(hrefJavaScriptRegex, 'href="#"')
96
+ .replace(hrefRegexForJsonString, 'href=\\"#\\"') // This will ensure to remain the content in json format for BEE editor
97
+ .replace(regexForUnicode, "")
98
+ .replace(srcWithJavaScriptRegex, 'src="#"')
99
+ .replace(globalJavascriptRegex, '""')
100
+ .replace(styleImportRegex, "")
101
+ .replace(jsBuiltInFunctionRegex, "")
102
+ .replace(unclosedOrSelfClosedTagRegex, "")
103
+ .replace(evalRegex, "");
104
+ return content;
105
+ } catch (err) {
106
+ console.error("Error while sanitizing template with Regexp", err, content);
107
+ return content;
108
+ }
109
+ };
110
+
111
+ export default sanitizeTemplateWithRegexp;