Get the FREE Ultimate OpenClaw Setup Guide →

security

Scanned
npx machina-cli add skill xiaobei930/cc-best/security --openclaw
Files (1)
SKILL.md
8.7 KB

安全审查技能

关联 Agent: security-reviewer(安全审查主力)、code-reviewer(代码审查中的安全维度)

本技能确保所有代码遵循安全最佳实践,识别潜在漏洞。

触发条件

  • 实现认证或授权
  • 处理用户输入或文件上传
  • 创建新的 API 端点
  • 使用密钥或凭证
  • 实现支付功能
  • 存储或传输敏感数据
  • 集成第三方 API

安全检查清单

1. 密钥管理

❌ 绝对禁止

const apiKey = "sk-proj-xxxxx"; // 硬编码密钥
const dbPassword = "password123"; // 源码中的密码

✅ 正确做法

const apiKey = process.env.OPENAI_API_KEY;
const dbUrl = process.env.DATABASE_URL;

// 验证密钥存在
if (!apiKey) {
  throw new Error("OPENAI_API_KEY 未配置");
}
import os

api_key = os.getenv("API_KEY")
if not api_key:
    raise ValueError("API_KEY 未配置")

检查项

  • 无硬编码的 API 密钥、Token 或密码
  • 所有密钥在环境变量中
  • .env.local 在 .gitignore 中
  • Git 历史中无密钥
  • 生产密钥在托管平台配置

2. 输入验证

始终验证用户输入

import { z } from "zod";

const CreateUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1).max(100),
  age: z.number().int().min(0).max(150),
});

export async function createUser(input: unknown) {
  const validated = CreateUserSchema.parse(input);
  return await db.users.create(validated);
}
from pydantic import BaseModel, validator

class UserCreate(BaseModel):
    email: str
    name: str
    age: int

    @validator("age")
    def validate_age(cls, v):
        if v < 0 or v > 150:
            raise ValueError("年龄无效")
        return v

文件上传验证

function validateFileUpload(file: File) {
  // 大小检查 (5MB 限制)
  const maxSize = 5 * 1024 * 1024;
  if (file.size > maxSize) {
    throw new Error("文件过大 (最大 5MB)");
  }

  // 类型检查
  const allowedTypes = ["image/jpeg", "image/png", "image/gif"];
  if (!allowedTypes.includes(file.type)) {
    throw new Error("文件类型不允许");
  }

  // 扩展名检查
  const allowedExtensions = [".jpg", ".jpeg", ".png", ".gif"];
  const extension = file.name.toLowerCase().match(/\.[^.]+$/)?.[0];
  if (!extension || !allowedExtensions.includes(extension)) {
    throw new Error("文件扩展名无效");
  }

  return true;
}

检查项

  • 所有用户输入使用 Schema 验证
  • 文件上传限制(大小、类型、扩展名)
  • 不直接在查询中使用用户输入
  • 白名单验证(非黑名单)
  • 错误消息不泄露敏感信息

3. SQL 注入防护

❌ 绝不拼接 SQL

// 危险 - SQL 注入漏洞
const query = `SELECT * FROM users WHERE email = '${userEmail}'`;
await db.query(query);
# 危险
query = f"SELECT * FROM users WHERE email = '{email}'"
cursor.execute(query)

✅ 始终使用参数化查询

// 安全 - 参数化查询
const { data } = await supabase
  .from("users")
  .select("*")
  .eq("email", userEmail);

// 或原生 SQL
await db.query("SELECT * FROM users WHERE email = $1", [userEmail]);
# 安全
cursor.execute(
    "SELECT * FROM users WHERE email = ?",
    (email,)
)

检查项

  • 所有数据库查询使用参数化
  • SQL 中无字符串拼接
  • ORM/查询构建器正确使用

4. 认证与授权

JWT Token 处理

// ❌ 错误: localStorage (易受 XSS 攻击)
localStorage.setItem("token", token);

// ✅ 正确: httpOnly cookies
res.setHeader(
  "Set-Cookie",
  `token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`,
);

授权检查

export async function deleteUser(userId: string, requesterId: string) {
  // 始终先验证授权
  const requester = await db.users.findUnique({
    where: { id: requesterId },
  });

  if (requester.role !== "admin") {
    return NextResponse.json({ error: "无权限" }, { status: 403 });
  }

  await db.users.delete({ where: { id: userId } });
}

检查项

  • Token 存储在 httpOnly cookies(非 localStorage)
  • 敏感操作前验证授权
  • 实现基于角色的访问控制
  • 会话管理安全

5. XSS 防护

净化 HTML

import DOMPurify from 'isomorphic-dompurify'

function renderUserContent(html: string) {
  const clean = DOMPurify.sanitize(html, {
    ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p'],
    ALLOWED_ATTR: []
  })
  return <div dangerouslySetInnerHTML={{ __html: clean }} />
}

CSP 头配置

// next.config.js
const securityHeaders = [
  {
    key: "Content-Security-Policy",
    value: `
      default-src 'self';
      script-src 'self';
      style-src 'self' 'unsafe-inline';
      img-src 'self' data: https:;
    `
      .replace(/\s{2,}/g, " ")
      .trim(),
  },
];

检查项

  • 用户提供的 HTML 已净化
  • CSP 头已配置
  • 无未验证的动态内容渲染
  • 使用框架的内置 XSS 防护

6. CSRF 防护

export async function POST(request: Request) {
  const token = request.headers.get("X-CSRF-Token");

  if (!csrf.verify(token)) {
    return NextResponse.json({ error: "CSRF Token 无效" }, { status: 403 });
  }
  // 处理请求
}

检查项

  • 状态变更操作有 CSRF Token
  • 所有 Cookie 使用 SameSite=Strict
  • 双重提交 Cookie 模式

7. 速率限制

import rateLimit from "express-rate-limit";

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 分钟
  max: 100, // 每窗口 100 请求
  message: "请求过多",
});

// 对搜索等昂贵操作更严格限制
const searchLimiter = rateLimit({
  windowMs: 60 * 1000, // 1 分钟
  max: 10,
  message: "搜索请求过多",
});
from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)

@app.get("/api/search")
@limiter.limit("10/minute")
async def search(request: Request):
    pass

检查项

  • 所有 API 端点有速率限制
  • 昂贵操作更严格限制
  • 基于 IP 的速率限制
  • 认证用户的速率限制

8. 敏感数据暴露

日志

// ❌ 错误: 记录敏感数据
console.log("用户登录:", { email, password });

// ✅ 正确: 脱敏
console.log("用户登录:", { email, userId });

错误消息

// ❌ 错误: 暴露内部细节
catch (error) {
  return { error: error.message, stack: error.stack }
}

// ✅ 正确: 通用错误消息
catch (error) {
  console.error('内部错误:', error)
  return { error: '发生错误,请重试' }
}

检查项

  • 日志中无密码、Token 或密钥
  • 用户看到通用错误消息
  • 详细错误仅在服务器日志
  • 堆栈跟踪不暴露给用户

9. 依赖安全

# 检查漏洞
npm audit
pip-audit

# 修复
npm audit fix

# 更新依赖
npm update
pip install --upgrade package

# 检查过期包
npm outdated

检查项

  • 依赖保持更新
  • 无已知漏洞 (npm audit clean)
  • Lock 文件已提交
  • 启用 Dependabot

10. 命令注入防护

# ❌ 危险
import os
os.system(f"echo {user_input}")

# ✅ 安全
import subprocess
subprocess.run(["echo", user_input], shell=False)
// ❌ 危险
exec(`process ${userInput}`);

// ✅ 安全
execFile("process", [userInput]);

11. 路径遍历防护

# ❌ 危险
file_path = f"/uploads/{filename}"

# ✅ 安全
import os
safe_name = os.path.basename(filename)
file_path = os.path.join("/uploads", safe_name)

安全测试

详见 verify-checklist.md — 包含认证、授权、输入验证、速率限制的测试示例。

部署前安全检查清单

详见 verify-checklist.md — 15 项生产部署前必查项。

专题安全指南

详细的专题安全内容请参考:

  • 云基础设施安全: cloud-security.md - IAM、密钥管理、CI/CD、网络安全

参考资源


记住:安全不是可选项。一个漏洞可能危及整个平台。有疑问时,选择更安全的方案。

Source

git clone https://github.com/xiaobei930/cc-best/blob/main/skills/security/SKILL.mdView on GitHub

Overview

Provides a comprehensive security review checklist and practical patterns to ensure code follows security best practices. It helps identify vulnerabilities across authentication, input handling, secrets management, API endpoints, and data flows.

How This Skill Works

Organized into sections such as key management, input validation, SQL injection, authentication/authorization, and XSS with concrete examples in TypeScript and Python. Developers apply the patterns—like environment-based keys, schema validation, parameterized queries, httpOnly cookies, and strict access checks—and iterate using the checklist.

When to Use It

  • Implementing authentication or authorization in a service
  • Handling user input or file uploads
  • Creating new API endpoints
  • Storing or transmitting secrets or credentials
  • Integrating third‑party APIs or payment functionality

Quick Start

  1. Step 1: Scan code for hard-coded keys, secrets, and insecure storage
  2. Step 2: Introduce environment-based configuration, input validation, and parameterized queries
  3. Step 3: Add robust auth checks and run security reviews against the checklist

Best Practices

  • Never hard-code API keys, tokens, or passwords
  • Store keys in environment variables and add local env files to .gitignore
  • Validate all user input with a schema (e.g., zod or pydantic)
  • Use parameterized queries to avoid SQL injection and never concatenate strings
  • Store tokens in httpOnly cookies, enforce proper authorization checks, and limit privileges

Example Use Cases

  • Replace hard-coded credentials with environment-based configs
  • Validate input against schemas before DB operations
  • Always use parameterized SQL queries
  • Use httpOnly, Secure cookies for tokens and enforce authorization
  • Implement file-upload checks for size, type, and extension

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers