这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天
Cross-Site Scripting(XSS)
通过某种方式将脚本注入到页面中
主要利用了
- string -> dom
- document . write
- element. innerHTML=anyString
- SSR(user_data) // 伪代码
特点
- 通常难以从 UI 上感知(暗地执行脚本)
- 窃取用户信息 (cookie/token)
- 绘制 UI(例如弹窗),诱骗用户点击/填写表单
Stored XSS
- 恶意脚本被存在数据库中
- 访问页面 -> 读数据 === 被攻击
- 危害最大,对全部用户可见
demo
public async submit(ctx){
const {content,id} = ctx.request.body
await db.save({
content,
id
})
}
public async render(ctx){
const {content} = await db.query({
id:ctx.query.id
})
ctx.body = `<div>${content}</div`;
}
在这段demo中,就没有对content进行过滤,那我们就可以通过直接提交恶意脚本😈
fetch('/submit',{
body:JSON.stringify({
id:"1",
content:`<script>alert("xss");</script>`
})
})
这样代码就会被渲染为这样子
ctx.body =`
<div>
<script>alert("xss");</script>
</div>
`
Reflected XSS
Demo
如果攻击者通过url将传递的字段给我们的页面的时候
public async render(ctx){
const {param} =ctx.query;
ctx.status = 200
ctx.body = `<div>${param}</div>`;
}
DOM-based XSS
这里依旧从url下手,
const content = new URL( Locat ion.href).searchParams.get("param")
const div = document. createElement("div"),
//
恶意脚本注入
div.innerHTML = content;
document.body.append(div);
Reflected vs DOM-based
我们可以看到上面的两种类型的攻击非常的相似,但是reflected攻击是在服务端注入,dom攻击是在浏览器那边执行整个闭环
Mutation-based XSS
- 利用了浏览器渲染 DOM 的特性(独特优化)
- 不同浏览器,会有区别(按浏览器进行攻击)
demo
<noscript><p title="</noscript><img src=x onerror=alert(1)>"
在很多的xss过滤工具中,都会把这段代码当做正常的代码来处理,但是把这段html拿到浏览器里渲染,比如放到Chrome中,就会得到以下结果
<div>
<noscript><p title="< /noscript>
<img src="x" onerror="alert (1) ">
</div>
可以看到noscript标签将p标签单独渲染,而img标签另外渲染,由于scr里面的内容不规范,img标签会触发onerror事件,从而达到攻击
Cross-site request forgery(CSRF) 跨站伪造请求
这里有一个用户,他收到一封email,里面有一个链接,是一个恶意的页面,那这个恶意页面伪造者伪造了一个http请求,比如说向银行发起一个转账请求,假设银行的服务器收到这么一个请求,而且用户的cookie和其他什么的都合法,那么就执行这个转账接口,完成转账,返回结果,那么用户平白无故就会丢失一笔财产
demo
<a href="https://bank. com/transfer?to=hacker&amount=100">点我抽奖</a>
<!-- 确实中奖了 -->
<!-- OR -->
<img style="display:none;"src= "https://bank. com/transfer?to=hacker&amount=100"/>
Injection
SQL Injection
demo
public async renderForm(ctx){
const { username, form_id } = ctx.query;
const result = await sql.query(
`SELECT a, b,
C FROM table
WHERE username =
${username)
AND form_id = ${ form_ id}
`
);
ctx. body = renderForm( result);
}
demo2
例如,这里接受客户端传递过来的参数,但是没有对参数进行过滤
public async convertVideo(ctx){
const { video options } = ctx.request.body;
exec(`convert-cli ${video} -o ${options)`);
ctx. body = "ok";
}
那么攻击者可以在参数中传递一个系统命令,例如rm之类的,当服务端进行执行命令的时候,服务器就执行这段命令,这时候服务器就有可能宕机。
fetch("/api", {
method: "POST",
body: JSON.stringify({
options:`&& rm -rf xxx`
})
});
读取+修改
部署的时候不要将重要文件(密码之类的)暴露出来,否则会被转发到其他地方进行访问,如果做社交网站的话,这种情况会经常出现
SSRF demo
如果没有对callback进行过滤,那么攻击者有可能构造一些内网的链接,从而执行一些内网才能执行的操作,进而暴露我们的内网链接
public async webhook(ctx) {
// callback 可能是内网 url
/ e.g http://secret. com/get_employ_ payrolls
ctx.body = await fetch(ctx.query.callback);
}
//访问 callback === 暴露内网信息
Denial of Service(DoS)
通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而雪崩效应。
ReDoS
比如服务器端写了一个贪婪的正则表达式,攻击者传入一个容易发生回溯行为的字符串,这样就导致服务器端响应时间大大增加
DDos
短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成。全部请求,导致请求堆积,进而雪崩效应,无法响应新请求。
中间人攻击
- 基于传输层
- 明文传输
- 信息篡改不可知
- 对方身份未验证
总结
本次学习收获颇多,了解到了很多关于网络安全的术语,也了解到了关于web开发安全的一系列攻击,这样让我了解到以后开发项目要留意这些攻击,防止以后工作中受坑。