Web开发安全 - 攻击篇| 青训营笔记

175 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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

image-20230206145022322.png

如果攻击者通过url将传递的字段给我们的页面的时候

public async render(ctx){
  const {param} =ctx.query;
  ctx.status = 200
  ctx.body = `<div>${param}</div>`;
}

DOM-based XSS

image-20230206150239944.png 这里依旧从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) 跨站伪造请求

image-20230206151356905.png

这里有一个用户,他收到一封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

image-20230206152847450.png

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.bodyexec(`convert-cli ${video} -o ${options)`);
ctx. body = "ok";
}

那么攻击者可以在参数中传递一个系统命令,例如rm之类的,当服务端进行执行命令的时候,服务器就执行这段命令,这时候服务器就有可能宕机。

fetch("/api", {
  method: "POST",
  body: JSON.stringify({
  options:`&& rm -rf xxx`
    })
});

读取+修改

部署的时候不要将重要文件(密码之类的)暴露出来,否则会被转发到其他地方进行访问,如果做社交网站的话,这种情况会经常出现

image-20230206153638337.png

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

短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成。全部请求,导致请求堆积,进而雪崩效应,无法响应新请求。

中间人攻击

  • 基于传输层
  • 明文传输
  • 信息篡改不可知
  • 对方身份未验证

image-20230206161629440.png

总结

本次学习收获颇多,了解到了很多关于网络安全的术语,也了解到了关于web开发安全的一系列攻击,这样让我了解到以后开发项目要留意这些攻击,防止以后工作中受坑。