mcpField
O
owasp-top-10

owasp-top-10

github.com/yonatangross安全29946 次安装1 天前更新
代码仓库

关于 owasp-top-10

owasp-top-10 是面向开发者的 Web 安全技能,按 OWASP Top 10 风险提供漏洞缓解说明与代码示例,涵盖访问控制、注入和 JWT 安全等主题。

主要功能

  1. 01OWASP Top 10 风险说明
  2. 02访问控制与 IDOR 修复建议
  3. 03参数化查询防注入
  4. 04密码与 JWT 安全检查
  5. 05依赖扫描和安全日志建议

适用场景

  1. 01检查 Web 应用的常见安全风险
  2. 02为 SQL 注入或 IDOR 编写修复
  3. 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