██╗ ██╗███████╗███████╗ ╚██╗██╔╝██╔════╝██╔════╝ ╚███╔╝ ███████╗███████╗ ██╔██╗ ╚════██║╚════██║ ██╔╝ ██╗███████║███████║ ╚═╝ ╚═╝╚══════╝╚══════╝
document.body.innerHTML='<script>alert(1)</script>' // 不执行js document.body.innerHTML='<img src="x" onerror=\'alert(1)\'>' // 执行js document.body.innerHTML='<img src="x" onerror=alert(1)>' // 执行js document.body.innerHTML='<img src="x"/onerror="alert(1)">' // 执行js
tunnel.html <body><script>eval(unescape(atob(location.search.slice(1))))</script></body> ... '/tunnel.html?' + btoa(escape(jscode)) b = new Function('alert(2)') b()
setTimeout('alert(4)', 0) setInterval('alert(5)', 5000) document.write('<script>alert(3)</script>')
# tail -f mb_accesslog 45.33.104.18 - - [09/Mar/2020:22:12:29 +0800] "GET /?cookie=BIDUPSID=4B3A1F21C50AA81B...省略...BD_HOME=1 HTTP/1.1" 301 5 "https://www.baidu.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36"
对于服务端渲染(SSR, 如PHP, JSP) 要考虑的是变量可能会注入一个存储型XSS脚本,需要注意清理HTML.
<div> $varUnsafe </div>
对于客户端(主要是浏览器)渲染,如vue渲染,主要是在使用v-html(innerHTML) 拼接html时,需注意相关数据要清理。
const encodeHTML = (str) => { return str .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, ''') // 也可以替换成 ''',x27是十六进制对应十进制39(ASCII码39表示单引号)
https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
从服务端拿到了存储的html代码,需要根据实际业务情况进行HTML 清理(wiki:HTML sanitization)
function cleanHTML(html) { const disallowedTags = ['script', 'style', 'link', 'math', 'iframe', 'svg', 'object'] const allowedAttrs = ['class', 'id'] const doc = new DOMParser().parseFromString(html, 'text/html'); const allElements = doc.querySelectorAll('*'); allElements.forEach(element => { // 遍历所有元素,移除所有黑名单标签,移除所有白名单属性之外的属性 if (disallowedTags.includes(element.tagName.toLowerCase())) { element.remove(); } else { Array.from(element.attributes).forEach(attr => { if (!allowedAttrs.includes(attr.name)) { element.removeAttribute(attr.name); // 如果属性不在白名单中,删除该属性 } }); } }); return doc.body.innerHTML }
DOMPurify 是一个广泛使用的 HTML 清理库,核心思路之一是把传入的 HTML 内容解析成 DOM 树,并对 DOM 树进行清理,通过一系列规则和过滤器移除不安全的标签、属性和脚本,清理潜在的安全风险。DOMPurify 基于白名单的过滤机制,意味着它只允许一些被认为是安全的标签和属性。通过这种方式,任何不在白名单中的标签、属性或内容都会被清理掉。包括标签白名单和属性白名单。
DOMPurify 的核心代码文件 (purify.js) 主要包括以下几部分: