source: imaps-frontend/node_modules/bootstrap/js/src/util/sanitizer.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 2.9 KB
Line 
1/**
2 * --------------------------------------------------------------------------
3 * Bootstrap util/sanitizer.js
4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5 * --------------------------------------------------------------------------
6 */
7
8// js-docs-start allow-list
9const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
10
11export const DefaultAllowlist = {
12 // Global attributes allowed on any supplied element below.
13 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
14 a: ['target', 'href', 'title', 'rel'],
15 area: [],
16 b: [],
17 br: [],
18 col: [],
19 code: [],
20 dd: [],
21 div: [],
22 dl: [],
23 dt: [],
24 em: [],
25 hr: [],
26 h1: [],
27 h2: [],
28 h3: [],
29 h4: [],
30 h5: [],
31 h6: [],
32 i: [],
33 img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
34 li: [],
35 ol: [],
36 p: [],
37 pre: [],
38 s: [],
39 small: [],
40 span: [],
41 sub: [],
42 sup: [],
43 strong: [],
44 u: [],
45 ul: []
46}
47// js-docs-end allow-list
48
49const uriAttributes = new Set([
50 'background',
51 'cite',
52 'href',
53 'itemtype',
54 'longdesc',
55 'poster',
56 'src',
57 'xlink:href'
58])
59
60/**
61 * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation
62 * contexts.
63 *
64 * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
65 */
66// eslint-disable-next-line unicorn/better-regex
67const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i
68
69const allowedAttribute = (attribute, allowedAttributeList) => {
70 const attributeName = attribute.nodeName.toLowerCase()
71
72 if (allowedAttributeList.includes(attributeName)) {
73 if (uriAttributes.has(attributeName)) {
74 return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue))
75 }
76
77 return true
78 }
79
80 // Check if a regular expression validates the attribute.
81 return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp)
82 .some(regex => regex.test(attributeName))
83}
84
85export function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {
86 if (!unsafeHtml.length) {
87 return unsafeHtml
88 }
89
90 if (sanitizeFunction && typeof sanitizeFunction === 'function') {
91 return sanitizeFunction(unsafeHtml)
92 }
93
94 const domParser = new window.DOMParser()
95 const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')
96 const elements = [].concat(...createdDocument.body.querySelectorAll('*'))
97
98 for (const element of elements) {
99 const elementName = element.nodeName.toLowerCase()
100
101 if (!Object.keys(allowList).includes(elementName)) {
102 element.remove()
103 continue
104 }
105
106 const attributeList = [].concat(...element.attributes)
107 const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || [])
108
109 for (const attribute of attributeList) {
110 if (!allowedAttribute(attribute, allowedAttributes)) {
111 element.removeAttribute(attribute.nodeName)
112 }
113 }
114 }
115
116 return createdDocument.body.innerHTML
117}
Note: See TracBrowser for help on using the repository browser.