关于 owasp-top-10
owasp-top-10 是面向开发者的 Web 安全技能,按 OWASP Top 10 风险提供漏洞缓解说明与代码示例,涵盖访问控制、注入和 JWT 安全等主题。
主要功能
- 01OWASP Top 10 风险说明
- 02访问控制与 IDOR 修复建议
- 03参数化查询防注入
- 04密码与 JWT 安全检查
- 05依赖扫描和安全日志建议
适用场景
- 01检查 Web 应用的常见安全风险
- 02为 SQL 注入或 IDOR 编写修复
- 03审查密码处理与 JWT 配置
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill owasp-top-10安装后在 Claude Code 中输入/owasp-top-10确认已加载。
附带文件examples/owasp-top10-fixes.mdreferences/vulnerability-demos.md
详细介绍
OWASP Top 10
防范最严重的 Web 安全风险。
1. 访问控制失效
# ❌ Bad: No authorization check
@app.route('/api/users/<user_id>')
def get_user(user_id):
return db.query(f"SELECT * FROM users WHERE id = {user_id}")
# ✅ Good: Verify user can access resource
@app.route('/api/users/<user_id>')
@login_required
def get_user(user_id):
if current_user.id != user_id and not current_user.is_admin:
abort(403)
return db.query("SELECT * FROM users WHERE id = ?", [user_id])
2. 加密失效
# ❌ Bad: Weak hashing
import hashlib
password_hash = hashlib.md5(password.encode()).hexdigest()
# ✅ Good: Strong hashing
from argon2 import PasswordHasher
ph = PasswordHasher()
password_hash = ph.hash(password)
3. 注入
# ❌ Bad: SQL injection vulnerable
query = f"SELECT * FROM users WHERE email = '{email}'"
# ✅ Good: Parameterized query
query = "SELECT * FROM users WHERE email = ?"
db.execute(query, [email])
4. 不安全的设计
- 登录未实施速率限制
- ID 按顺序递增或容易猜测
- 敏感操作未使用 CAPTCHA
修复: 使用 UUID,实施速率限制,并尽早进行威胁建模。
5. 安全配置错误
# ❌ Bad: Debug mode in production
app.debug = True
# ✅ Good: Environment-based config
app.debug = os.getenv('FLASK_ENV') == 'development'
6. 易受攻击的组件
# Scan for vulnerabilities
npm audit
pip-audit
# Fix vulnerabilities
npm audit fix
7. 身份验证失效
# ✅ Strong password requirements
def validate_password(password):
if len(password) < 12:
return "Password must be 12+ characters"
if not re.search(r"[A-Z]", password):
return "Must contain uppercase"
if not re.search(r"[0-9]", password):
return "Must contain number"
return None
JWT 安全(OWASP 最佳实践)
import jwt
import hashlib
import secrets
from datetime import datetime, timezone, timedelta
# ❌ Bad: Trust algorithm from header
payload = jwt.decode(token, SECRET, algorithms=jwt.get_unverified_header(token)['alg'])
# ✅ Good: Hardcode expected algorithm (prevents algorithm confusion attacks)
def verify_jwt(token: str) -> dict:
try:
payload = jwt.decode(
token,
SECRET_KEY,
algorithms=['HS256'], # NEVER read from header
options={
'require': ['exp', 'iat', 'iss', 'aud'], # Required claims
}
)
# Validate issuer and audience
if payload['iss'] != EXPECTED_ISSUER:
raise jwt.InvalidIssuerError()
if payload['aud'] != EXPECTED_AUDIENCE:
raise jwt.InvalidAudienceError()
return payload
except jwt.ExpiredSignatureError:
raise AuthError("Token expired")
except jwt.InvalidTokenError as e:
raise AuthError(f"Invalid token: {e}")
# Token sidejacking protection (OWASP recommended)
def create_protected_token(user_id: str, response) -> str:
"""Create token with user context to prevent sidejacking."""
# Generate random fingerprint
fingerprint = secrets.token_urlsafe(32)
# Store fingerprint hash in token (not raw value)
payload = {
'user_id': user_id,
'fingerprint': hashlib.sha256(fingerprint.encode()).hexdigest(),
'exp': datetime.now(timezone.utc) + timedelta(minutes=15),
'iat': datetime.now(timezone.utc),
'iss': ISSUER,
'aud': AUDIENCE,
}
# Send raw fingerprint as hardened cookie
response.set_cookie(
'__Secure-Fgp', # Cookie prefix for extra security
fingerprint,
httponly=True,
secure=True,
samesite='Strict',
max_age=900 # 15 min
)
return jwt.encode(payload, SECRET_KEY, algorithm='HS256')
JWT 安全检查清单:
- 将算法硬编码(绝不从标头读取)
- 验证 exp、iat、iss、aud 声明
- 设置较短的过期时间(15 分钟 - 1 小时)
- 较长会话使用刷新令牌轮换
- 实施令牌拒绝列表,以支持登出和撤销
8. 数据完整性失效
<script src="https://cdn.example.com/lib.js"
integrity="sha384-..."
crossorigin="anonymous"></script>
9. 日志记录失效
# ✅ Log security events
@app.route('/login', methods=['POST'])
def login():
user = authenticate(email, password)
if user:
logger.info(f"Successful login: {email}")
else:
logger.warning(f"Failed login: {email}")
10. SSRF(服务端请求伪造)
# ❌ Bad: Fetch any URL
response = requests.get(user_provided_url)
# ✅ Good: Allowlist domains
ALLOWED = ['api.example.com']
if urlparse(url).hostname not in ALLOWED:
abort(400)
快速检查清单
- 对所有端点进行授权检查
- 使用 bcrypt/argon2 对密码进行哈希处理
- 仅使用参数化查询
- 已启用速率限制
- 生产环境中已关闭调试模式
- 定期扫描依赖项
- 记录安全事件
相关技能
auth-patterns- 身份验证实现input-validation- 清理模式security-scanning- 自动化扫描
能力详情
injection
关键词: SQL 注入、命令注入、注入、参数化 解决的问题:
- 防止 SQL 注入
- 修复命令注入
- 使用参数化查询
access-control
关键词: 访问控制、授权、IDOR、权限 解决的问题:
- 修复访问控制失效
- 防止 IDOR 漏洞
- 实施授权检查
owasp-fixes
关键词: 修复、缓解、示例、漏洞 解决的问题:
- 修复 OWASP 漏洞
- 缓解措施示例
- 代码修复模式
评论
支持 Markdown