input 标签本身不执行脚本,但若用户输入未经转义直接拼入 value 或 placeholder 属性(如 value="{{ userinput }}"),攻击者可用对应引号闭合属性并注入事件,如输入" onfocus=alert(1)。

input 标签本身不会执行脚本,但它是 XSS 的高危中转站——只要用户输入被不加处理地拼回 HTML(比如赋值给 value、placeholder 或通过 innerHTML 插入),漏洞就成立了。
value 和 placeholder 属性必须按引号类型转义
把用户数据塞进 value="{{ userInput }}" 或 placeholder='{{ userInput }}' 时,攻击者可用对应引号提前闭合属性,再注入事件。比如输入 " onfocus=alert(1),最终生成:<input value="" onfocus='alert(1)"'>。
- 双引号包裹的属性(
value="xxx")必须转义"→" - 单引号包裹的属性(
placeholder='xxx')必须转义'→' - 若服务端已返回 HTML 实体编码过的字符串(如
<script></script>),前端不能再对它二次转义,否则显示为字面量
绝对不要用 innerHTML 渲染 input 的 value 回显
常见错误:后端返回 JSON,前端取 data.username 后直接 el.innerHTML = '<input value="' + data.username + '">'。此时哪怕用户名是 " onclick=alert(1),也会触发执行。
- 正确做法:用
el.value = data.username(原生 DOM 属性赋值,浏览器自动隔离) - 或用
setAttribute('value', data.username),但需确保传入前已按上下文转义 - 避免字符串拼接 HTML;若必须动态生成 input,优先用
document.createElement('input')+ 属性设置
contenteditable + input 混用是隐形炸弹
有些组件用 div contenteditable="true" 模拟 input 行为,再通过 JS 把内容同步到隐藏 input。这等于主动开启富文本入口——用户可输入 <img src="https://img.php.cn/?x-oss-process=image/resize,p_40" alt="HTML中input标签如何防止XSS跨站脚本攻击">,浏览器会立刻解析执行。
- 除非业务强依赖富文本编辑,否则别用
contenteditable替代input - 若必须用,同步到
input.value前,先过DOMPurify.sanitize(dirtyHtml)过滤,再提取纯文本(textContent)赋值 - 切记:
contenteditable的值不是“用户输入”,而是“可执行 HTML 片段”
最易被忽略的一点:同一个用户输入可能同时出现在 value、placeholder、URL 参数、甚至内联 JS 字符串里——每个位置需要的转义方式完全不同。只做一遍 HTML 实体转义,解决不了问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











