aboutsummaryrefslogtreecommitdiff
path: root/js/src/util/sanitizer.js
diff options
context:
space:
mode:
authorBobby <[email protected]>2024-08-16 20:47:33 -0400
committerGitHub <[email protected]>2024-08-16 20:47:33 -0400
commit6b28433d9cfde435be8ec2bd6cf91e6324d08865 (patch)
tree8343c27b8b95ff5639233e81cf157f92e5688466 /js/src/util/sanitizer.js
parentd53094ec16ba385faae2973ddee648698b32ab24 (diff)
parent048f56f51460df75e92a2f7b472e1c56baeb68f7 (diff)
downloadbootstrap-6b28433d9cfde435be8ec2bd6cf91e6324d08865.tar.xz
bootstrap-6b28433d9cfde435be8ec2bd6cf91e6324d08865.zip
Merge branch 'twbs:main' into mainHEADmain
Diffstat (limited to 'js/src/util/sanitizer.js')
-rw-r--r--js/src/util/sanitizer.js91
1 files changed, 45 insertions, 46 deletions
diff --git a/js/src/util/sanitizer.js b/js/src/util/sanitizer.js
index 5a7a68035..3d2883aff 100644
--- a/js/src/util/sanitizer.js
+++ b/js/src/util/sanitizer.js
@@ -1,53 +1,13 @@
/**
* --------------------------------------------------------------------------
- * Bootstrap (v5.1.3): util/sanitizer.js
+ * Bootstrap util/sanitizer.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
-const uriAttributes = new Set([
- 'background',
- 'cite',
- 'href',
- 'itemtype',
- 'longdesc',
- 'poster',
- 'src',
- 'xlink:href'
-])
-
+// js-docs-start allow-list
const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
-/**
- * A pattern that recognizes a commonly useful subset of URLs that are safe.
- *
- * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
- */
-const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i
-
-/**
- * A pattern that matches safe data URLs. Only matches image, video and audio types.
- *
- * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
- */
-const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i
-
-const allowedAttribute = (attribute, allowedAttributeList) => {
- const attributeName = attribute.nodeName.toLowerCase()
-
- if (allowedAttributeList.includes(attributeName)) {
- if (uriAttributes.has(attributeName)) {
- return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue))
- }
-
- return true
- }
-
- // Check if a regular expression validates the attribute.
- return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp)
- .some(regex => regex.test(attributeName))
-}
-
export const DefaultAllowlist = {
// Global attributes allowed on any supplied element below.
'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
@@ -57,7 +17,10 @@ export const DefaultAllowlist = {
br: [],
col: [],
code: [],
+ dd: [],
div: [],
+ dl: [],
+ dt: [],
em: [],
hr: [],
h1: [],
@@ -81,14 +44,51 @@ export const DefaultAllowlist = {
u: [],
ul: []
}
+// js-docs-end allow-list
+
+const uriAttributes = new Set([
+ 'background',
+ 'cite',
+ 'href',
+ 'itemtype',
+ 'longdesc',
+ 'poster',
+ 'src',
+ 'xlink:href'
+])
+
+/**
+ * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation
+ * contexts.
+ *
+ * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
+ */
+// eslint-disable-next-line unicorn/better-regex
+const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i
+
+const allowedAttribute = (attribute, allowedAttributeList) => {
+ const attributeName = attribute.nodeName.toLowerCase()
+
+ if (allowedAttributeList.includes(attributeName)) {
+ if (uriAttributes.has(attributeName)) {
+ return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue))
+ }
+
+ return true
+ }
+
+ // Check if a regular expression validates the attribute.
+ return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp)
+ .some(regex => regex.test(attributeName))
+}
-export function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {
+export function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {
if (!unsafeHtml.length) {
return unsafeHtml
}
- if (sanitizeFn && typeof sanitizeFn === 'function') {
- return sanitizeFn(unsafeHtml)
+ if (sanitizeFunction && typeof sanitizeFunction === 'function') {
+ return sanitizeFunction(unsafeHtml)
}
const domParser = new window.DOMParser()
@@ -100,7 +100,6 @@ export function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {
if (!Object.keys(allowList).includes(elementName)) {
element.remove()
-
continue
}