AI 做安全审计的优势和局限
AI 在代码安全审计中有独特的优势:
- 它见过海量的漏洞模式,能识别常见的安全问题
- 它不会疲劳,不会因为代码太长而漏看
- 它能同时从多个维度分析代码
但也有明显的局限:
- 它可能产生误报(False Positive)
- 它无法发现需要运行时才能暴露的问题
- 它不了解你的业务上下文
- 它不能替代专业的渗透测试
所以,AI 安全审计的定位是:第一道防线,不是最后一道。
通用安全审计提示词
你是一个资深安全工程师。请对以下代码进行安全审计。
代码:
```[语言]
[代码]
审计范围:
- OWASP Top 10 漏洞
- 业务逻辑漏洞
- 配置安全问题
输出格式: 对每个发现的问题,请提供:
- 严重程度:🔴 高危 / 🟡 中危 / 🟢 低危
- 漏洞类型:[CWE 编号和名称]
- 问题位置:[文件名:行号]
- 问题描述:[详细说明]
- 攻击场景:[如何被利用]
- 修复建议:[具体的修复代码]
最后给出整体安全评分(1-10)和优先修复建议。
---
## OWASP Top 10 专项审计
### 1. 注入攻击(Injection)
请检查以下代码中的注入漏洞,包括但不限于:
- SQL 注入
- NoSQL 注入
- OS 命令注入
- LDAP 注入
- XPath 注入
代码:
[代码]
对每个发现,请:
- 指出具体的注入点
- 给出攻击 payload 示例
- 给出使用参数化查询的修复代码
#### 审计示例
输入代码:
```python
from flask import Flask, request
import sqlite3
app = Flask(__name__)
@app.route('/users')
def search_users():
name = request.args.get('name', '')
conn = sqlite3.connect('app.db')
cursor = conn.cursor()
# 直接拼接用户输入到 SQL
cursor.execute(f"SELECT * FROM users WHERE name LIKE '%{name}%'")
users = cursor.fetchall()
return {'users': users}
@app.route('/ping')
def ping():
host = request.args.get('host', '')
import os
# 直接拼接用户输入到系统命令
result = os.popen(f'ping -c 1 {host}').read()
return {'result': result}
AI 审计输出:
🔴 高危 | CWE-89: SQL Injection
位置:第 10 行
描述:用户输入 name 直接拼接到 SQL 查询中,攻击者可以注入任意 SQL。
攻击 payload:name='; DROP TABLE users; --
修复:
# 使用参数化查询
cursor.execute(
"SELECT * FROM users WHERE name LIKE ?",
(f'%{name}%',)
)
---
🔴 高危 | CWE-78: OS Command Injection
位置:第 17 行
描述:用户输入 host 直接拼接到系统命令中,攻击者可以执行任意命令。
攻击 payload:host=127.0.0.1; cat /etc/passwd
修复:
import subprocess
import shlex
# 使用 subprocess 并验证输入
import re
if not re.match(r'^[\w.-]+$', host):
return {'error': 'Invalid host'}, 400
result = subprocess.run(
['ping', '-c', '1', host],
capture_output=True, text=True, timeout=5
)
return {'result': result.stdout}
整体安全评分:2/10
优先修复:立即修复 SQL 注入和命令注入,这两个都是可以直接被利用的高危漏洞。
2. XSS 检测
请检查以下前端代码中的 XSS(跨站脚本)漏洞:
- 反射型 XSS
- 存储型 XSS
- DOM 型 XSS
代码:
```[语言]
[代码]
对每个发现,请:
- 指出 XSS 类型
- 给出攻击 payload
- 给出使用转义/CSP 的修复方案
#### 常见 XSS 模式
| 模式 | 危险代码 | 安全替代 |
|------|---------|---------|
| innerHTML | `el.innerHTML = userInput` | `el.textContent = userInput` |
| document.write | `document.write(data)` | 使用 DOM API |
| eval | `eval(userInput)` | 永远不要 eval 用户输入 |
| React dangerouslySetInnerHTML | `dangerouslySetInnerHTML={{__html: data}}` | 使用 DOMPurify 清洗 |
| Vue v-html | `v-html="userData"` | 使用 `{{ userData }}` 插值 |
---
### 3. 认证和会话管理
请审查以下代码的认证和会话管理安全性:
代码:
[代码]
检查项:
- 密码存储方式(是否使用 bcrypt/argon2)
- Session/Token 管理(过期、刷新、撤销)
- 密码重置流程安全性
- 多因素认证实现
- 暴力破解防护
- Session fixation 防护
#### 审计示例
```python
# 不安全的认证代码
import hashlib
def register(username, password):
# 问题 1:使用 MD5 存储密码
password_hash = hashlib.md5(password.encode()).hexdigest()
db.save_user(username, password_hash)
def login(username, password):
user = db.get_user(username)
password_hash = hashlib.md5(password.encode()).hexdigest()
if user.password_hash == password_hash:
# 问题 2:Token 没有过期时间
token = generate_token(user.id)
return {'token': token}
# 问题 3:没有登录失败次数限制
return {'error': 'Invalid credentials'}, 401
AI 审计输出:
🔴 高危 | CWE-328: 使用弱哈希算法
位置:register 函数
描述:使用 MD5 存储密码。MD5 已被证明不安全,可以被彩虹表攻击。
修复:
import bcrypt
def register(username, password):
# 使用 bcrypt,自动加盐
password_hash = bcrypt.hashpw(
password.encode(), bcrypt.gensalt(rounds=12)
)
db.save_user(username, password_hash)
---
🟡 中危 | CWE-613: Session 过期不足
位置:login 函数
描述:生成的 Token 没有设置过期时间。
修复:
import jwt
from datetime import datetime, timedelta
def login(username, password):
# ...验证密码...
token = jwt.encode(
{
'user_id': user.id,
'exp': datetime.utcnow() + timedelta(hours=24),
'iat': datetime.utcnow(),
},
SECRET_KEY,
algorithm='HS256'
)
return {'token': token}
---
🟡 中危 | CWE-307: 暴力破解防护缺失
位置:login 函数
描述:没有限制登录失败次数,攻击者可以无限尝试密码。
修复:
from functools import lru_cache
import time
# 简单的速率限制
login_attempts = {}
def login(username, password):
# 检查失败次数
key = f"login:{username}"
attempts = login_attempts.get(key, {"count": 0, "last": 0})
if attempts["count"] >= 5 and time.time() - attempts["last"] < 900:
return {'error': 'Too many attempts. Try again in 15 minutes.'}, 429
# ...验证逻辑...
if not valid:
attempts["count"] += 1
attempts["last"] = time.time()
login_attempts[key] = attempts
4. 敏感数据暴露
请检查以下代码中的敏感数据暴露问题:
代码:
```[语言]
[代码]
检查项:
- 硬编码的密钥、密码、Token
- 日志中是否打印敏感信息
- 错误信息是否泄露内部细节
- API 响应是否包含不必要的敏感字段
- 是否使用 HTTPS
- 敏感数据是否加密存储
---
### 5. 访问控制
请审查以下代码的访问控制实现:
代码:
[代码]
检查项:
- 是否存在越权访问(水平越权/垂直越权)
- API 端点是否都有权限检查
- 文件上传是否有路径遍历风险
- 是否存在 IDOR(不安全的直接对象引用)
- 管理员功能是否有额外保护
#### IDOR 示例
```python
# 不安全:用户可以通过修改 ID 访问其他用户的订单
@app.route('/orders/<order_id>')
def get_order(order_id):
order = db.get_order(order_id) # 没有检查订单是否属于当前用户
return order
# 安全:验证订单归属
@app.route('/orders/<order_id>')
@login_required
def get_order(order_id):
order = db.get_order(order_id)
if order.user_id != current_user.id:
abort(403)
return order
依赖安全检查
请分析以下项目的依赖安全性。
依赖文件:
[package.json / requirements.txt / go.mod 内容]
请检查:
1. 是否有已知漏洞的依赖版本
2. 是否有不再维护的依赖
3. 是否有可疑的依赖(typosquatting)
4. 依赖版本是否锁定
5. 给出升级建议
安全报告生成
请根据以下安全审计发现,生成一份正式的安全审计报告。
审计发现:
[审计结果列表]
报告格式:
1. 执行摘要(给管理层看的)
2. 审计范围和方法
3. 发现汇总表(按严重程度排序)
4. 详细发现(每个问题的完整描述)
5. 修复建议和优先级
6. 整体风险评估
输出示例
# 安全审计报告
## 执行摘要
对 [项目名] 进行了代码安全审计,共发现 12 个安全问题:
- 高危:3 个
- 中危:5 个
- 低危:4 个
最严重的问题是 SQL 注入和命令注入漏洞,建议立即修复。
## 发现汇总
| # | 严重程度 | 类型 | 位置 | 状态 |
|---|---------|------|------|------|
| 1 | 🔴 高危 | SQL 注入 | api/users.py:45 | 待修复 |
| 2 | 🔴 高危 | 命令注入 | api/tools.py:23 | 待修复 |
| 3 | 🔴 高危 | 硬编码密钥 | config.py:12 | 待修复 |
| 4 | 🟡 中危 | XSS | templates/profile.html:67 | 待修复 |
| 5 | 🟡 中危 | 弱密码哈希 | auth/password.py:15 | 待修复 |
| ... | ... | ... | ... | ... |
## 修复优先级
1. 立即修复(本周内):#1, #2, #3
2. 尽快修复(两周内):#4, #5, #6, #7, #8
3. 计划修复(一个月内):#9, #10, #11, #12
自动化安全审计流程
把安全审计集成到 CI/CD 中:
import json
def automated_security_audit(code_files: list[str]) -> dict:
"""自动化安全审计流程"""
all_findings = []
for file_path in code_files:
with open(file_path) as f:
code = f.read()
# 第 1 步:通用安全扫描
findings = call_llm(f"""请对以下代码进行安全审计。
只输出 JSON 格式的发现列表。
代码文件:{file_path}
{code}
JSON 格式:
[{{"severity": "high/medium/low", "type": "漏洞类型", "line": 行号, "description": "描述", "fix": "修复建议"}}]""")
file_findings = json.loads(findings)
for f in file_findings:
f["file"] = file_path
all_findings.extend(file_findings)
# 第 2 步:生成报告
high_count = sum(1 for f in all_findings if f["severity"] == "high")
medium_count = sum(1 for f in all_findings if f["severity"] == "medium")
report = {
"total_findings": len(all_findings),
"high": high_count,
"medium": medium_count,
"low": len(all_findings) - high_count - medium_count,
"findings": all_findings,
"pass": high_count == 0 # 有高危漏洞则不通过
}
return report
使用建议
1. 分模块审计
不要把整个项目一次性丢给 AI。按模块审计,每次聚焦一个文件或一个功能。
2. 结合静态分析工具
AI 审计 + 传统 SAST 工具(如 Semgrep、SonarQube)互补使用,效果最好。
3. 定期审计
不是做一次就完了。每次重大功能更新后都应该重新审计。
4. 验证修复
修复后再跑一次审计,确认问题确实被修复了,而且没有引入新问题。
安全审计不是找茬,而是在攻击者之前找到问题。AI 让这个过程更快、更全面,但最终的安全意识和安全文化,还是要靠团队中的每一个人。
相关文章
评论
加载中...
评论
加载中...