网站渗透测试入门:OWASP Top 10 漏洞检测与修复指南

OWASP(Open Web Application Security Project)Top 10 是 Web 应用安全领域最权威的漏洞分类标准。了解这些常见的漏洞类型及其修复方法,是保障网站安全的基础。

一、OWASP Top 10(2026版)

A01:失效的访问控制

漏洞描述:攻击者可以访问未授权的功能或数据。

常见场景

  • 通过修改 URL 中的 ID 访问其他用户数据:/user/123/user/456
  • 越权删除或修改其他用户的内容
  • 未登录即可访问管理后台

检测方法

# 测试水平越权
curl -b "session=user_a" /api/orders/123
curl -b "session=user_b" /api/orders/123  # 应该返回 403

# 测试垂直越权
curl /admin/users  # 未登录应该返回 401/403

修复方案

// 每次请求检查用户权限
if ($_SESSION['user_id'] !== $requested_user_id) {
    http_response_code(403);
    die('Unauthorized');
}

// 使用中间件统一鉴权
$router->group(['middleware' => 'auth:admin'], function() {
    // 管理后台路由
});

A02:加密机制失效

漏洞描述:敏感数据未正确加密,或在传输过程中暴露。

常见问题

  • 使用 HTTP 而不是 HTTPS
  • 密码使用 MD5/SHA1 存储
  • 信用卡号、身份证号未加密存储
  • 使用过时的 TLS 版本

修复方案

// 密码哈希
$hashed = password_hash($password, PASSWORD_BCRYPT);

// 验证密码
if (password_verify($password, $hashed)) {
    // 登录成功
}

A03:注入

漏洞描述:SQL 注入、命令注入、LDAP 注入等。

检测方法

# SQL 注入测试
curl 'https://example.com/product?id=1'  # 正常
curl 'https://example.com/product?id=1%27'  # 单引号 - 可能触发错误
curl "https://example.com/product?id=1' OR '1'='1"  # 注入尝试

修复方案

// 使用预处理语句(PDO)
$stmt = $pdo->prepare('SELECT * FROM products WHERE id = ?');
$stmt->execute([$productId]);

// 永远不要拼接 SQL
// ❌ $sql = "SELECT * FROM products WHERE id = $productId";

A04:不安全的设计

漏洞描述:应用程序架构设计层面的安全缺陷。

示例

  • 密码重置流程不需要身份验证
  • 接口没有速率限制
  • 信任客户端传来的价格数据

修复方案

// 服务端验证价格,不信任前端数据
$product = $pdo->query("SELECT price FROM products WHERE id = $productId");
if ($_POST['price'] < $product['price']) {
    die('价格异常');
}

A05:安全配置错误

漏洞描述:默认配置、未修补的漏洞、目录列表等。

检测清单

- [ ] 删除默认账户和密码
- [ ] 关闭目录列表
- [ ] 移除调试信息和错误详情
- [ ] 更新所有组件到最新版本
- [ ] 配置正确的安全头部
- [ ] 最小权限原则配置

A06:易受攻击和过时的组件

漏洞描述:使用了有已知漏洞的第三方组件。

检测方法

# Node.js
npm audit --production

# PHP
composer audit

# Python
pip list --outdated
safety check

A07:识别和认证失败

漏洞描述:身份验证机制不完善。

常见问题

  • 允许弱密码
  • 没有登录失败限制
  • Session 固定或未正确过期
  • 密码重置功能存在漏洞

修复方案

// 密码强度要求
if (strlen($password) < 8 || 
    !preg_match('/[A-Z]/', $password) ||
    !preg_match('/[a-z]/', $password) ||
    !preg_match('/[0-9]/', $password)) {
    die('密码不符合要求');
}

// 登录失败限制
if ($loginAttempts[$ip] >= 5) {
    die('登录次数过多,请 15 分钟后重试');
}

A08:软件和数据完整性失效

漏洞描述:CI/CD 流程或软件更新过程中的安全问题。

修复方案

- 验证第三方库的签名和哈希
- 使用锁文件(package-lock.json、composer.lock)
- CI/CD 流程中的安全检查
- 代码签名验证

A09:安全日志记录和监控不足

漏洞描述:无法及时发现和响应安全事件。

配置建议

日志记录要求:
- 记录所有登录尝试(成功和失败)
- 记录权限变更操作
- 记录敏感数据操作
- 日志不可篡改(写一次,追加)
- 实时告警异常行为
- 定期审查日志

A10:服务端请求伪造(SSRF)

漏洞描述:攻击者利用服务器发起内网请求。

检测方法

# SSRF 测试
curl 'https://example.com/fetch?url=http://169.254.169.254/'  # 元数据端点
curl 'https://example.com/fetch?url=http://localhost/admin'

修复方案

// URL 白名单
$allowedDomains = ['api.trusted.com', 'cdn.example.com'];
$url = parse_url($_GET['url']);
if (!in_array($url['host'], $allowedDomains)) {
    die('URL 不在白名单中');
}

// 禁用 HTTP 重定向
$context = stream_context_create(['http' => ['follow_location' => false]]);
$content = file_get_contents($url, false, $context);

二、渗透测试工具

工具 用途 难度
OWASP ZAP 自动化漏洞扫描
Burp Suite 手动渗透测试
SQLMap SQL 注入自动化检测
Nikto Web 服务器扫描
Nmap 端口和服务发现
Metasploit 漏洞利用框架

三、修复优先级

高优先级(立即修复):
- SQL 注入
- 失效的访问控制(越权)
- XSS(存储型)
- 敏感数据泄露

中优先级(本周内修复):
- XSS(反射型)
- CSRF
- 安全配置错误
- 使用过时的组件

低优先级(本月内修复):
- 缺少安全头部
- 日志不完善
- UI 信息泄露

四、如何组织一次渗透测试

拿到一份测试报告前,先想清楚怎么组织测试本身。一个标准的 Web 渗透测试通常分五个阶段:

  1. 范围确认:明确测试哪些域名、接口、账号权限,并拿到书面授权。没有授权的"扫描"在法律上是入侵,不是测试。
  2. 信息收集:通过子域名枚举、指纹识别、目录爆破了解攻击面,常用 subfinderhttpxffuf
  3. 自动化扫描:用 OWASP ZAP 或 Burp 打底,覆盖常见注入、XSS 与错误配置。
  4. 手动验证:对扫描结果逐条人工确认,排除误报,并对登录、支付、上传等核心流程做深度测试。
  5. 报告与复测:按风险分级输出报告,修复后复测确认。
# 信息收集常用命令
subfinder -d example.com -silent | httpx -silent -status-code
ffuf -w /usr/share/wordlists/dirb/common.txt -u https://example.com/FUZZ

一份可执行的测试计划至少包含以下要素:

项目 说明
测试目标 域名、子域、接口清单
授权范围 允许的操作与时间窗口
账号等级 匿名 / 普通用户 / 管理员
排除项 不测的接口(如支付网关直连)
交付物 报告格式、复测周期

一次小型电商网站的测试案例

假设一个年流水 500 万的小型电商第一次做渗透测试。自动化扫描先发现 12 个中高危问题,手动复测后真正确认 5 个:商品评论处有一个存储型 XSS(未过滤 HTML)、/api/order/ 存在越权接口(未校验订单归属)、目录列出、后台弱口令、缺少 CSP 头。修复优先级很清晰:越权接口和存储型 XSS 当天修,弱口令改策略,其余两周内处理。关键点:漏洞数量并不可怕,可怕的是不知道哪些是真问题、哪些要优先修。

五、总结

渗透测试不是一次性工作,而是应该融入开发周期的持续流程。对于大多数网站,使用 OWASP ZAP 定期扫描 + 手动测试关键功能就能发现大部分常见漏洞。修复漏洞时遵循"先修补高危,再优化常规"的原则。记住,安全是一个持续的过程,不是终点。