浅谈XSS攻击
跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页面时,嵌入Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击!
XSS分为:存储型 、反射型 、DOM型XSS
存储型XSS:存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie
反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。反射型XSS大多数是用来盗取用户的Cookie信息。
DOM型XSS:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。 DOM的详解:DOM文档对象模型
1DOM型
可能触发DOM型XSS的属性
document.referer
window.name
location
innerHTML
documen.write
大多数为一些前端漏洞,如下是一个通过url获取图片案例
<input type="text" id="web"/> <button id="add">添加图片</button> <div class="box"></div>
<script> //不基于后端 DOM-Based 修改属性 插入内容document.write //改变结构后会造成攻击 //攻击内容 xss payload //使用encodeURI转义 $('#add').on('click',function () { //<img src='xxx' onerror='alert(1)' id=''> // $('.box').html(`<img src=${$('#web').val()}>`); $('.box').html(`<img src=${encodeURI($('#web').val())}>`); }) </script>
示例图
加上encodeURI转义后,可以看到onerror被转义了,阻止了弹窗效果。
2反射型
//反射型 http://localhost:3000/welcome?type=<script>alert(document.cookie)</script>,可以获取cookie等 //有些浏览器有xss屏蔽功能,也可以后端设置不可以获取cookie,res.cookie(SESSION_ID, cardId,{httpOnly:true});降低受损范围,不是解决方案 //诱导用户自己点开(一次性) //查询参数可以加上encodeURIComponent app.get("/welcome", (req, res) => { // res.send(`${req.query.type}`); res.send(`${encodeURIComponent(req.query.type)}`); });
上述代码未转义之前也能通过<script>标签获取个人信息等
3存储型
影响范围最广,例如下面一个模拟评论功能的xss攻击
页面
<ul id="ul"></ul> <hr/> <input type="text" id="content" ><button id="btn">点击添加</button> <script> //获取数据 function getList(){ let html='' $.get('/getList').then(res=>{ if(res.code===0){ const ulList = res.ulList ulList.forEach(e => { html+=`<li>name:${e.name},content:${e.content}</li>` }); $('#ul').html(html) } }) } getList() //添加数据 $('#btn').on('click',function(){ const content = $('#content').val() $.post('/addList',{content}).then(res=>{ if(res.code===0){ //添加成功 getList(); }else{ location.href = '/login.html' } }) }) </script>
server.js
//模拟存储数据 const ulList = [{ name: "李四", content: "你好,李四" }]; //获取数据 app.get("/getList", (req, res) => { res.json({ code: 0, ulList }); }); //添加数据 app.post("/addList", (req, res) => { const { content } = req.body; //cookie相关 const r = session[req.cookies[SESSION_ID]] || {}; const user = r.user; if (user) { //已登录 ulList.push({ name: user.username, content }); res.json({ code: 0 }); } else { res.json({ code: 1, error: "用户未登录" }); } });
如图,也是通过<script>标签可以获取用户数据,此范围是直接存储在服务器,每个人到当前页面调用数据都会被窃取,范围性更大,也可以通过转义进行拦截。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通