From b51f51fbdf51839339c7ad640bc5fe6b954ae92a Mon Sep 17 00:00:00 2001 From: xanhacks Date: Wed, 27 Sep 2023 13:08:35 +0200 Subject: [PATCH] add infinite depth --- README.md | 2 +- docs/index.html | 30 +++++++++++++++++++++++++++++- docs/js/utils.js | 16 ++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a1db780..0e219f4 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ List of tags which supports the name attribute: const tags = ["a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "h1", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "portal", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp"]; const attributes = ["accept", "accept-charset", "accesskey", "action", "align", "allow", "alt", "async", "autocapitalize", "autocomplete", "autofocus", "autoplay", "background", "bgcolor", "border", "buffered", "capture", "challenge", "charset", "checked", "cite", "class", "code", "codebase", "color", "cols", "colspan", "content", "contenteditable", "contextmenu", "controls", "coords", "crossorigin", "csp", "data", "data-*", "datetime", "decoding", "default", "defer", "dir", "dirname", "disabled", "download", "draggable", "enctype", "enterkeyhint", "for", "form", "formaction", "formenctype", "formmethod", "formnovalidate", "formtarget", "headers", "height", "hidden", "high", "href", "hreflang", "http-equiv", "id", "integrity", "intrinsicsize", "inputmode", "ismap", "itemprop", "keytype", "kind", "label", "lang", "language", "loading", "list", "loop", "low", "manifest", "max", "maxlength", "minlength", "media", "method", "min", "multiple", "muted", "name", "novalidate", "open", "optimum", "pattern", "ping", "placeholder", "playsinline", "poster", "preload", "readonly", "referrerpolicy", "rel", "required", "reversed", "role", "rows", "rowspan", "sandbox", "scope", "scoped", "selected", "shape", "size", "sizes", "slot", "span", "spellcheck", "src", "srcdoc", "srclang", "srcset", "start", "step", "style", "summary", "tabindex", "target", "title", "translate", "type", "usemap", "value", "width", "wrap"]; -let valids = {}; +var valids = {}; tags.forEach(tag => { attributes.forEach(attribute => { if (attribute != "id" && attribute != "name") { diff --git a/docs/index.html b/docs/index.html index 2a335fc..1141794 100644 --- a/docs/index.html +++ b/docs/index.html @@ -119,9 +119,37 @@

DOM Clobbering Payloads Generator

if (documentScope) { setNote('Unable to set the value of this variable, retry without "document." or by using "window." instead.'); } else { - setNote('The variable will be defined, but the variable value will be inside the ".value" property.'); + setNote(`The variable "${variableName}" will be defined, but the variable\'s value will be inside the "${variableName}.value" property.`); payloads.push(`
\n\t\n
\n
`); } + } else { + setNote('You need "form" and "input" to generate a payload of this depth.'); + } + } else if (depth === 4) { + const [first, second, third, fourth] = variableName.split("."); + + if (ALLOWED_ELEMENTS.includes("iframe") && ALLOWED_ELEMENTS.includes("a")) { + setNote(`The variable "${variableName}" will be defined, but the variable\'s value will be inside the "${variableName}.value" property.`); + payloads.push(``); + } else { + setNote('You need "iframe" and "a" to generate a payload of this depth.'); + } + } else { + const elements = variableName.split("."); + if (ALLOWED_ELEMENTS.includes("iframe") && ALLOWED_ELEMENTS.includes("a")) { + setNote(`The variable "${variableName}" will be defined, but the variable\'s value will be inside the "${variableName}.value" property.`); + + var payload = ""; + for (let i = 0; i < elements.length - 1; i++) { + payload += quoteEncode(``, i); + } + payloads.push(payload); + } else { + setNote('You need "iframe" and "a" to generate a payload of this depth.'); } } diff --git a/docs/js/utils.js b/docs/js/utils.js index c244370..7ac4895 100644 --- a/docs/js/utils.js +++ b/docs/js/utils.js @@ -67,4 +67,20 @@ function setNote(message) { function clearNote() { note.textContent = ''; note.style.display = 'none'; +} + +/** + * HTML encode quotes one or multiple times. + * @param {string} html - HTML string to encode. + * @param {int} numberOfTimes - Number of times to encode the quotes. + * @returns The HTML string with the quotes encoded. + */ +function quoteEncode(html, numberOfTimes) { + if (numberOfTimes == 0) return html; + + let encoded = html.replace(/"/g, '"') + for (let i = 0; i < numberOfTimes - 1; i++) { + encoded = encoded.replace(/&/g, '&'); + } + return encoded; } \ No newline at end of file