这是我参与「第四届青训营 」笔记创作活动的第6天
Day6 Web开发安全之旅
eg:Steam白嫖漏洞
两个角度:攻击者(Hacker)、防御者(Developer)
攻击者
XSS(Cross-Site Scripting)
概念
将恶意脚本注入进来(盲目信任用户的输入),导致用户访问时执行恶意脚本
特点
- 通常难以从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请求,伪造或修改用户信息
实例
模拟权限转钱
攻击方式
<a href = "xinanzhijia.xyz">你中了100万</a><img style="display:none" src="www.2school.com/images/200"></img>- 构造表单
<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)
实例
中间人攻击(基于传输层)
概念
浏览器认为自己在和服务器交互,服务器认为自己在给浏览器返回数据,但他们其实都在和一个第三方(恶意浏览器、路游器、代理公司)进行交互。
如何防护?
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防护
方法一
我们有办法判断:哪些请求是合法的?
方法二(SameSite Cookie)
别的页面不允许带上别的用户的cookie,一个cookie只能给一个用户使用
Set-Cookie : SameSite=None; Secure
| SameSite | CORS |
|---|---|
| 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
总结
- 安全无大小
- 道高一尺魔高一丈
- 永远保持学习和谦卑的心态