Day6 Web开发安全之旅 | 字节青训营

192 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第6天

Day6 Web开发安全之旅

eg:Steam白嫖漏洞

两个角度:攻击者(Hacker)、防御者(Developer)

攻击者

XSS(Cross-Site Scripting)

概念

将恶意脚本注入进来(盲目信任用户的输入),导致用户访问时执行恶意脚本

1.jpg

特点

  • 通常难以从UI上感知(暗地执行脚本)
  • 可以窃取用户信息(Cookie)
  • 伪造UI,诱骗用户点击(XSS可以执行JS脚本)

实例

public async submit(ctx){
  const {content,id} = ctx.request.body;
  // 没有对content进行过滤
  await db.save(
    {
      content,
      id  // 写入数据库
    })
}

public async render(ctx){
  const {content} = await db.query({
  // 没有对content进行过滤
    id:ctx.query.id
  });
  ctx.body = `<div>${content}></div>`;
}

如何进行XSS攻击呢?

可以把提交内容中的content 设置为 <script>alert("恭喜你中了100万");</script> 这样就在HTML中插入了一段script脚本,形成了XSS攻击。

分类

  • 存储型:刚刚的例子,恶意脚本被存在数据库中(可以攻击所有人)
  • 反射型:通过url攻击,无数据库,由Server层进行注入
  • DOM型:由浏览器进行注入,在浏览器完成整个闭环
  • 浏览器型:根据不同浏览器渲染方式,进行嵌入字符串的攻击(最难防御)

CSRF(Cross-site request forgery)

概念

跨站伪造请求

特点

  • 用户不知情的前提下
  • 利用用户的权限(cookie)
  • 构造指定HTTP请求,伪造或修改用户信息

实例

模拟权限转钱

2.jpg

攻击方式

  1. <a href = "xinanzhijia.xyz">你中了100万</a>
  2. <img style="display:none" src="www.2school.com/images/200"></img>
  3. 构造表单
<form action="login.php" method="post" accept-charset="utf-8" class="login">
    <p>Login</p>
    <input  type="text" placeholder="用户名" id="username" name="username">
    <input type="password" placeholder="密码" id="password" name="password">
    <input type="submit" class="btn" value="登  录">
</form>

SQL注入

概念

请求(参数:SQL恶意代码)→ 运行SQL恶意代码 → 意外的增删改查

实例

public async renderForm(ctx){
  const {username, form_id} = ctx.query;
  // 依旧不过滤username,password
  const result = await sql.query(
  	`SELECT a,b,c FROM table
	 WHERE username = $(username) AND password = $(password)`
  );
  ctx.body = renderForm(result);
}

直接注入:any; drop TABLE table 删库跑路!

同样的,我们也可以通过此类方法修改/etc/passwd, etc/nginx/nginx.conf 等等重要配置文件,修改Nginx代理或者直接获取服务器密码。

DoS(Denial of Service)

概念

通过某种方式,导致服务器资源被显著消耗,以至于无法相应更多的请求,服务器崩溃。

实例

补:正则贪婪匹配

const greedyRegExp = "/a+/"// 后面有多少匹配多少
const NongreedyRegExp = "/a+?/"// 只匹配一个

const str = "aaaaaa";

concole.log(str.match(greedyRegExp)[0]); // aaaaaa全部匹配
concole.log(str.match(NongreedyRegExp)[0]); // 只匹配一个a

可以通过贪婪匹配,攻击者传入一个经常回溯的字符串。这样导致服务器吞吐量明显降低。

Distributed Dos(DDoS)

概念

大量堆积请求(如TCP),导致请求堆积耗尽服务器带宽。 eg:洪水攻击(SYN Flood)

实例

3.jpg

中间人攻击(基于传输层)

概念

浏览器认为自己在和服务器交互,服务器认为自己在给浏览器返回数据,但他们其实都在和一个第三方(恶意浏览器、路游器、代理公司)进行交互。

4.jpg

如何防护?

XSS防护

主旨

永远不要相信用户提交的任何数据,不要把用户输入的内容作为DOM,而是当成字符串看待。

具体方法

前端

主流框架均防御XSS

谷歌提供的 Google-closure-library

后端(Node)

DOMPurify (npm包)

补:同源策略

http://xhr1314.top
https://xhr1314.top
https://www.xhr1314.top

这三者均不同源

CSP(Content Security Policy)

概念

哪些域名是安全的,来自安全域名的脚本直接执行;不是来自安全的不可以直接执行。

实例

服务器头部相应

Content-Security-Policy:script-src 'self' //同源
Content-Security-Policy:script-src 'self' https://xhr1314.top

浏览器meta

<meta http-equiv="Content-Security-Policy" content="script-src self"></meta>

CSRF防护

方法一

我们有办法判断:哪些请求是合法的?

5.jpg

方法二(SameSite Cookie)

别的页面不允许带上别的用户的cookie,一个cookie只能给一个用户使用

6.jpg

Set-Cookie : SameSite=None; Secure
SameSiteCORS
Cookie发送资源读写(HTTP请求)
domain VS 页面域名资源域名 VS 页面域名
“出了酒店,我就不认了”白名单

SQL注入防护

主旨

使用prepared statement,将sql编译。

注意事项:

  • 永远不要给sudo权限
  • 建立白名单,允许的命令才能被执行
  • 对url的参数类型进行限制,避免内网被访问

我们可以代码扫描、进行正则性能测试、并且拒绝用户提供的正则

DDoS防护

流量治理

  • 负载均衡
  • API网关
  • CDN

快速自动扩容

非核心服务降级

中间人攻击防护

主旨:HTTPS

可靠性:加密(避免明问传输)

完整性:MAC验证(确保信息没有被篡改)

不可抵赖性:数字签名(双方的身份得到保障)

可靠性

加密算法(非对称加密)

完整性

传输内容:

秘密信息+秘密信息_Hash

接收方:

if(hash(秘密信息)==秘密信息_Hash)
	OK;
else
	exit;

不可抵赖性(数字签名)

签名执行者:

privateKey(私钥自己藏好)

publicKey(公钥公开可见)

数字签名过程:

privateKey+内容  ---->(通过数学运算) signature

publicKey:
	校验生成的签名,如果私钥匹配则通过,否则不通过

怎样获取HTTPS

既然HTTPS这么好,怎样让我们的域名可以拥有HTTPS呢?

这里提供的办法仅限于大平台,例如腾讯云、阿里云购买的域名。这两家公司会提供一定数量的SSH证书。

我们去官网自己的控制台相关位置下载即可,得到SSH压缩包(其中包含一个PEM文件,一个KEY文件)

下面打开这两个文件,借助宝塔面板(这个功能宝塔面板没有问题),把这两个文件完完整整复制到对应位置,

一定要完完整整!

之后别忘了保存+右上角强制HTTPS

7.jpg

总结

  • 安全无大小
  • 道高一尺魔高一丈
  • 永远保持学习和谦卑的心态