(root)
| 6510 | /* Collect anything executable reachable from a serialized string, walking |
| 6511 | into <template>.content and any activated shadowRoot. */ |
| 6512 | const _executableFindings = function (root) { |
| 6513 | const findings = []; |
| 6514 | const visit = (node) => { |
| 6515 | if (!node) return; |
| 6516 | if (node.nodeType === 1) { |
| 6517 | const tag = node.tagName ? node.tagName.toLowerCase() : ''; |
| 6518 | for (const name of node.getAttributeNames()) { |
| 6519 | if (/^on/i.test(name)) findings.push(`${tag}@${name}`); |
| 6520 | if ( |
| 6521 | (name === 'href' || name === 'src' || name === 'xlink:href') && |
| 6522 | /^\s*(?:java|vb)script:/i.test(node.getAttribute(name) || '') |
| 6523 | ) { |
| 6524 | findings.push(`${tag}@${name}=js`); |
| 6525 | } |
| 6526 | } |
| 6527 | if (tag === 'script') findings.push('script'); |
| 6528 | if (node.shadowRoot) visit(node.shadowRoot); |
| 6529 | if (tag === 'template' && node.content) visit(node.content); |
| 6530 | } |
| 6531 | for (const child of node.childNodes) visit(child); |
| 6532 | }; |
| 6533 | visit(root); |
| 6534 | return findings; |
| 6535 | }; |
| 6536 | const _findingsFromHTML = function (html) { |
| 6537 | const holder = document.createElement('div'); |
| 6538 | holder.innerHTML = html; |
no test coverage detected