mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Update DOMPurify to version 3.1.4
This commit is contained in:
parent
51194f0fed
commit
58025b5ff4
4 changed files with 74 additions and 15 deletions
4
src/ui/static/js/utils/purify/purify.min.js
vendored
4
src/ui/static/js/utils/purify/purify.min.js
vendored
File diff suppressed because one or more lines are too long
3
src/ui/static/js/utils/purify/src/attrs.js
vendored
3
src/ui/static/js/utils/purify/src/attrs.js
vendored
|
|
@ -74,6 +74,9 @@ export const html = freeze([
|
|||
'pattern',
|
||||
'placeholder',
|
||||
'playsinline',
|
||||
'popover',
|
||||
'popovertarget',
|
||||
'popovertargetaction',
|
||||
'poster',
|
||||
'preload',
|
||||
'pubdate',
|
||||
|
|
|
|||
77
src/ui/static/js/utils/purify/src/purify.js
vendored
77
src/ui/static/js/utils/purify/src/purify.js
vendored
|
|
@ -15,6 +15,7 @@ import {
|
|||
stringToString,
|
||||
stringIndexOf,
|
||||
stringTrim,
|
||||
numberIsNaN,
|
||||
regExpTest,
|
||||
typeErrorCreate,
|
||||
lookupGetter,
|
||||
|
|
@ -22,6 +23,22 @@ import {
|
|||
objectHasOwnProperty,
|
||||
} from './utils.js';
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
|
||||
const NODE_TYPE = {
|
||||
element: 1,
|
||||
attribute: 2,
|
||||
text: 3,
|
||||
cdataSection: 4,
|
||||
entityReference: 5, // Deprecated
|
||||
entityNode: 6, // Deprecated
|
||||
progressingInstruction: 7,
|
||||
comment: 8,
|
||||
document: 9,
|
||||
documentType: 10,
|
||||
documentFragment: 11,
|
||||
notation: 12, // Deprecated
|
||||
};
|
||||
|
||||
const getGlobal = function () {
|
||||
return typeof window === 'undefined' ? null : window;
|
||||
};
|
||||
|
|
@ -88,7 +105,11 @@ function createDOMPurify(window = getGlobal()) {
|
|||
*/
|
||||
DOMPurify.removed = [];
|
||||
|
||||
if (!window || !window.document || window.document.nodeType !== 9) {
|
||||
if (
|
||||
!window ||
|
||||
!window.document ||
|
||||
window.document.nodeType !== NODE_TYPE.document
|
||||
) {
|
||||
// Not running in a browser, provide a factory function
|
||||
// so that you can pass your own Window
|
||||
DOMPurify.isSupported = false;
|
||||
|
|
@ -1024,7 +1045,7 @@ function createDOMPurify(window = getGlobal()) {
|
|||
}
|
||||
|
||||
/* Remove any ocurrence of processing instructions */
|
||||
if (currentNode.nodeType === 7) {
|
||||
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
||||
_forceRemove(currentNode);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1032,7 +1053,7 @@ function createDOMPurify(window = getGlobal()) {
|
|||
/* Remove any kind of possibly harmful comments */
|
||||
if (
|
||||
SAFE_FOR_XML &&
|
||||
currentNode.nodeType === 8 &&
|
||||
currentNode.nodeType === NODE_TYPE.comment &&
|
||||
regExpTest(/<[/\w]/g, currentNode.data)
|
||||
) {
|
||||
_forceRemove(currentNode);
|
||||
|
|
@ -1096,7 +1117,7 @@ function createDOMPurify(window = getGlobal()) {
|
|||
}
|
||||
|
||||
/* Sanitize element content to be template-safe */
|
||||
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
|
||||
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
|
||||
/* Get the element's text content */
|
||||
content = currentNode.textContent;
|
||||
|
||||
|
|
@ -1130,7 +1151,10 @@ function createDOMPurify(window = getGlobal()) {
|
|||
if (
|
||||
SANITIZE_DOM &&
|
||||
(lcName === 'id' || lcName === 'name') &&
|
||||
(value in document || value in formElement)
|
||||
(value in document ||
|
||||
value in formElement ||
|
||||
value === '__depth' ||
|
||||
value === '__removalCount')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1288,6 +1312,12 @@ function createDOMPurify(window = getGlobal()) {
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Work around a security issue with comments inside attributes */
|
||||
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
||||
_removeAttribute(name, currentNode);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Sanitize attribute content to be template-safe */
|
||||
if (SAFE_FOR_TEMPLATES) {
|
||||
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => {
|
||||
|
|
@ -1348,7 +1378,11 @@ function createDOMPurify(window = getGlobal()) {
|
|||
currentNode.setAttribute(name, value);
|
||||
}
|
||||
|
||||
arrayPop(DOMPurify.removed);
|
||||
if (_isClobbered(currentNode)) {
|
||||
_forceRemove(currentNode);
|
||||
} else {
|
||||
arrayPop(DOMPurify.removed);
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
|
|
@ -1380,7 +1414,7 @@ function createDOMPurify(window = getGlobal()) {
|
|||
const parentNode = getParentNode(shadowNode);
|
||||
|
||||
/* Set the nesting depth of an element */
|
||||
if (shadowNode.nodeType === 1) {
|
||||
if (shadowNode.nodeType === NODE_TYPE.element) {
|
||||
if (parentNode && parentNode.__depth) {
|
||||
/*
|
||||
We want the depth of the node in the original tree, which can
|
||||
|
|
@ -1393,8 +1427,15 @@ function createDOMPurify(window = getGlobal()) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Remove an element if nested too deeply to avoid mXSS */
|
||||
if (shadowNode.__depth >= MAX_NESTING_DEPTH) {
|
||||
/*
|
||||
* Remove an element if nested too deeply to avoid mXSS
|
||||
* or if the __depth might have been tampered with
|
||||
*/
|
||||
if (
|
||||
shadowNode.__depth >= MAX_NESTING_DEPTH ||
|
||||
shadowNode.__depth < 0 ||
|
||||
numberIsNaN(shadowNode.__depth)
|
||||
) {
|
||||
_forceRemove(shadowNode);
|
||||
}
|
||||
|
||||
|
|
@ -1478,7 +1519,10 @@ function createDOMPurify(window = getGlobal()) {
|
|||
elements being stripped by the parser */
|
||||
body = _initDocument('<!---->');
|
||||
importedNode = body.ownerDocument.importNode(dirty, true);
|
||||
if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
|
||||
if (
|
||||
importedNode.nodeType === NODE_TYPE.element &&
|
||||
importedNode.nodeName === 'BODY'
|
||||
) {
|
||||
/* Node is already a body, use as is */
|
||||
body = importedNode;
|
||||
} else if (importedNode.nodeName === 'HTML') {
|
||||
|
|
@ -1528,7 +1572,7 @@ function createDOMPurify(window = getGlobal()) {
|
|||
const parentNode = getParentNode(currentNode);
|
||||
|
||||
/* Set the nesting depth of an element */
|
||||
if (currentNode.nodeType === 1) {
|
||||
if (currentNode.nodeType === NODE_TYPE.element) {
|
||||
if (parentNode && parentNode.__depth) {
|
||||
/*
|
||||
We want the depth of the node in the original tree, which can
|
||||
|
|
@ -1541,8 +1585,15 @@ function createDOMPurify(window = getGlobal()) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Remove an element if nested too deeply to avoid mXSS */
|
||||
if (currentNode.__depth >= MAX_NESTING_DEPTH) {
|
||||
/*
|
||||
* Remove an element if nested too deeply to avoid mXSS
|
||||
* or if the __depth might have been tampered with
|
||||
*/
|
||||
if (
|
||||
currentNode.__depth >= MAX_NESTING_DEPTH ||
|
||||
currentNode.__depth < 0 ||
|
||||
numberIsNaN(currentNode.__depth)
|
||||
) {
|
||||
_forceRemove(currentNode);
|
||||
}
|
||||
|
||||
|
|
|
|||
5
src/ui/static/js/utils/purify/src/utils.js
vendored
5
src/ui/static/js/utils/purify/src/utils.js
vendored
|
|
@ -52,6 +52,11 @@ const regExpTest = unapply(RegExp.prototype.test);
|
|||
|
||||
const typeErrorCreate = unconstruct(TypeError);
|
||||
|
||||
export function numberIsNaN(x) {
|
||||
// eslint-disable-next-line unicorn/prefer-number-properties
|
||||
return typeof x === 'number' && isNaN(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new function that calls the given function with a specified thisArg and arguments.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue