diff options
| author | Bobby <[email protected]> | 2024-08-16 20:47:33 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-08-16 20:47:33 -0400 |
| commit | 6b28433d9cfde435be8ec2bd6cf91e6324d08865 (patch) | |
| tree | 8343c27b8b95ff5639233e81cf157f92e5688466 /js/src/util/sanitizer.js | |
| parent | d53094ec16ba385faae2973ddee648698b32ab24 (diff) | |
| parent | 048f56f51460df75e92a2f7b472e1c56baeb68f7 (diff) | |
| download | bootstrap-main.tar.xz bootstrap-main.zip | |
Diffstat (limited to 'js/src/util/sanitizer.js')
| -rw-r--r-- | js/src/util/sanitizer.js | 91 |
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 } |
