html实体编码本身不防xss,仅在特定上下文有效;必须转义、&、"、'这五个字符才能拦住基础xss,漏一即可能被绕过,且不同上下文(如属性、url、js)需匹配对应转义规则。

HTML代码本身不执行逻辑,但它是XSS漏洞最直接的载体;查漏洞不是看有没有<script></script>,而是看用户输入是否未经转义就进入了危险上下文。
哪些HTML属性一出现就要重点盯住
浏览器会主动解析并执行这些属性里的JS代码,只要值来自用户输入且未过滤,基本等于开门放攻击者进来:
-
onerror、onclick、onload等所有以on开头的事件处理器 -
href值为javascript:alert(1)或data:text/html;base64,...这类可执行协议 -
src或srcdoc指向动态拼接的字符串(比如iframe.src = '?id=' + location.search) -
style里含expression()(IE)或url(javascript:...)(部分旧版解析器)
innerHTML = userInput 这类写法必须立刻改掉
它把字符串当HTML解析,等于把攻击载荷直接喂给浏览器执行。和textContent有本质区别——后者只渲染纯文本,完全免疫XSS。
- 常见误判点:
document.write(userInput)、element.insertAdjacentHTML('beforeend', userInput)、Vue的v-html、React的dangerouslySetInnerHTML - 如果非得用
innerHTML,确保userInput已由服务端做过严格净化(不只是简单替换),且该场景不可替代 - 前端做转义只是辅助,不能替代后端对输出上下文的精确编码(比如插入到
value="..."里要用HTML属性实体,插入到JS字符串里要用JS字符串转义)
URL参数反射到页面时最容易漏掉的注入点
很多XSS藏在看似“静态”的回显逻辑里,比如从location.search取q=xxx,再填进<input value="xxx">——攻击者只要闭合引号就能注入事件。
- 测试payload:
" onfocus="alert(1),最终生成<input value="" onfocus="alert(1)">即中招 - 绕过手段常见:
"代替双引号、用oncut/oncontextmenu等冷门事件、在meta标签的content属性里塞JS - DOM型XSS尤其难发现:不经过服务器响应,全靠前端JS动态拼接,审查时容易只盯模板而忽略
location.hash、document.referrer、history.state等来源
真正危险的不是<script></script>标签,而是那些被浏览器当成代码执行的属性和API;人工审查时优先扫on*、javascript:、innerHTML、srcdoc,再结合W3C验证器看结构合法性,最后用Burp或ZAP跑一遍反射式测试——三者缺一不可。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











