mcpField
O
owasp-security-check

owasp-security-check

github.com/sergiodxa安全921.7k 次安装38 周前更新
代码仓库

关于 owasp-security-check

OWASP Security Check 是面向开发者的安全审计技能,用于检查 Web 应用和 REST API。其规则涵盖常见漏洞类别,并提供按严重程度审查、报告发现及给出修复建议的流程。

主要功能

  1. 01五类共 20 条规则
  2. 02按严重程度排序的审计流程
  3. 03检查身份验证与访问控制
  4. 04覆盖输入、API 和配置风险
  5. 05报告问题影响并提供修复示例

适用场景

  1. 01上线前审查 Web 应用
  2. 02评估身份验证与授权代码
  3. 03检查 REST API 安全性
  4. 04检查涉及敏感数据的功能变更

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sergiodxa/agent-skills --skill owasp-security-check

安装后在 Claude Code 中输入/owasp-security-check确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

rules/
api-security.md
authentication-failures.md
broken-access-control.md
cors-configuration.md
cryptographic-failures.md
csrf-protection.md
data-integrity-failures.md
file-upload-security.md
injection-attacks.md
insecure-design.md
logging-monitoring.md
rate-limiting.md
redirect-validation.md
secrets-management.md
security-headers.md
security-misconfiguration.md
sensitive-data-exposure.md
session-security.md
ssrf-attacks.md
vulnerable-dependencies.md

详细介绍

OWASP 安全检查

面向 Web 应用和 REST API 的全面安全审计模式。包含 5 个类别中的 20 条规则,涵盖 OWASP Top 10 和常见 Web 漏洞。

适用场景

在以下情况下使用此技能:

  • 审计代码库中的安全漏洞
  • 检查用户提供的文件或文件夹是否存在安全问题
  • 检查身份验证/授权实现
  • 评估 REST API 安全性
  • 评估数据保护措施
  • 检查配置和部署设置
  • 生产环境部署之前
  • 添加处理敏感数据的新功能之后

使用此技能的方法

  1. 识别应用类型——Web 应用、REST API、SPA、SSR 或混合类型
  2. 按优先级扫描——从 CRITICAL 规则开始,然后检查 HIGH,最后检查 MEDIUM
  3. 查看相关规则文件——从 @rules/ 目录加载特定规则
  4. 报告发现的问题——注明严重性、文件位置和影响
  5. 提供修复方案——给出具体的修复代码示例

审计工作流

步骤 1:按优先级系统化检查

按优先级检查各类别:

  1. CRITICAL:身份验证与授权、数据保护、输入/输出安全
  2. HIGH:配置与标头
  3. MEDIUM:API 与监控
步骤 2:生成报告

按以下格式记录发现的问题:

  • Severity:CRITICAL | HIGH | MEDIUM | LOW
  • Category:规则名称
  • File:路径和行号
  • Issue:问题所在
  • Impact:安全影响
  • Fix:修复方案的代码示例

规则摘要

身份验证与授权(CRITICAL)
broken-access-control - @rules/broken-access-control.md

检查是否缺少授权、存在 IDOR 或权限提升问题。

// Bad: No authorization check
async function getUser(req: Request): Promise<Response> {
  let url = new URL(req.url);
  let userId = url.searchParams.get("id");
  let user = await db.user.findUnique({ where: { id: userId } });
  return new Response(JSON.stringify(user));
}

// Good: Verify ownership
async function getUser(req: Request): Promise<Response> {
  let session = await getSession(req);
  let url = new URL(req.url);
  let userId = url.searchParams.get("id");

  if (session.userId !== userId && !session.isAdmin) {
    return new Response("Forbidden", { status: 403 });
  }

  let user = await db.user.findUnique({ where: { id: userId } });
  return new Response(JSON.stringify(user));
}
authentication-failures - @rules/authentication-failures.md

检查身份验证是否薄弱、是否缺少 MFA,以及会话是否存在问题。

// Bad: Weak password check
if (password.length >= 6) {
  /* allow */
}

// Good: Strong password requirements
function validatePassword(password: string) {
  if (password.length < 12) return false;
  if (!/[A-Z]/.test(password)) return false;
  if (!/[a-z]/.test(password)) return false;
  if (!/[0-9]/.test(password)) return false;
  if (!/[^A-Za-z0-9]/.test(password)) return false;
  return true;
}
数据保护(CRITICAL)
cryptographic-failures - @rules/cryptographic-failures.md

检查加密是否薄弱、是否以明文存储,以及哈希处理是否不当。

// Bad: MD5 for passwords
let hash = crypto.createHash("md5").update(password).digest("hex");

// Good: bcrypt with salt
let hash = await bcrypt(password, 12);
sensitive-data-exposure - @rules/sensitive-data-exposure.md

检查日志/响应中是否包含 PII,以及错误消息是否泄露信息。

// Bad: Exposing sensitive data
return new Response(JSON.stringify(user)); // Contains password hash, email, etc.

// Good: Return only needed fields
return new Response(
  JSON.stringify({
    id: user.id,
    username: user.username,
    displayName: user.displayName,
  }),
);
data-integrity-failures - @rules/data-integrity-failures.md

检查是否存在未经签名的数据和不安全的反序列化。

// Bad: Trusting unsigned JWT
let decoded = JSON.parse(atob(token.split(".")[1]));
if (decoded.isAdmin) {
  /* grant access */
}

// Good: Verify signature
let payload = await verifyJWT(token, secret);
secrets-management - @rules/secrets-management.md

检查是否硬编码机密,以及环境变量是否暴露。

// Bad: Hardcoded secret
const API_KEY = "sk_live_a1b2c3d4e5f6";

// Good: Environment variables
let API_KEY = process.env.API_KEY;
if (!API_KEY) throw new Error("API_KEY not configured");
输入/输出安全(CRITICAL)
injection-attacks - @rules/injection-attacks.md

检查是否存在 SQL、XSS、NoSQL、命令注入和路径遍历注入。

// Bad: SQL injection
let query = `SELECT * FROM users WHERE email = '${email}'`;

// Good: Parameterized query
let user = await db.user.findUnique({ where: { email } });
ssrf-attacks - @rules/ssrf-attacks.md

检查 URL 是否经过验证,以及是否能访问内部网络。

// Bad: Fetching user-provided URL
let url = await req.json().then((d) => d.url);
let response = await fetch(url);

// Good: Validate against allowlist
const ALLOWED_DOMAINS = ["api.example.com", "cdn.example.com"];
let url = new URL(await req.json().then((d) => d.url));
if (!ALLOWED_DOMAINS.includes(url.hostname)) {
  return new Response("Invalid URL", { status: 400 });
}
file-upload-security - @rules/file-upload-security.md

检查上传是否不受限制,以及是否验证 MIME 类型。

// Bad: No file type validation
let file = await req.formData().then((fd) => fd.get("file"));
await writeFile(`./uploads/${file.name}`, file);

// Good: Validate type and extension
const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/webp"];
const ALLOWED_EXTS = [".jpg", ".jpeg", ".png", ".webp"];
let file = await req.formData().then((fd) => fd.get("file") as File);

if (!ALLOWED_TYPES.includes(file.type)) {
  return new Response("Invalid file type", { status: 400 });
}
redirect-validation - @rules/redirect-validation.md

检查是否存在开放重定向,以及重定向 URL 是否经过验证。

// Bad: Unvalidated redirect
let returnUrl = new URL(req.url).searchParams.get("return");
return Response.redirect(returnUrl);

// Good: Validate redirect URL
let returnUrl = new URL(req.url).searchParams.get("return");
let allowed = ["/dashboard", "/profile", "/settings"];
if (!allowed.includes(returnUrl)) {
  return Response.redirect("/");
}
配置与标头(HIGH)
insecure-design - @rules/insecure-design.md

检查架构中是否存在安全反模式。

// Bad: Security by obscurity
let isAdmin = req.headers.get("x-admin-secret") === "admin123";

// Good: Proper role-based access control
let session = await getSession(req);
let isAdmin = await db.user
  .findUnique({
    where: { id: session.userId },
  })
  .then((u) => u.role === "ADMIN");
security-misconfiguration - @rules/security-misconfiguration.md

检查是否存在默认配置、调试模式和错误处理问题。

// Bad: Exposing stack traces
catch (error) {
  return new Response(error.stack, { status: 500 });
}

// Good: Generic error message
catch (error) {
  console.error(error); // Log server-side only
  return new Response("Internal server error", { status: 500 });
}
security-headers - @rules/security-headers.md

检查 CSP、HSTS、X-Frame-Options 等安全标头。

// Bad: No security headers
return new Response(html);

// Good: Security headers set
return new Response(html, {
  headers: {
    "Content-Security-Policy": "default-src 'self'",
    "X-Frame-Options": "DENY",
    "X-Content-Type-Options": "nosniff",
    "Strict-Transport-Security": "max-age=31536000; includeSubDomains",
  },
});
cors-configuration - @rules/cors-configuration.md

检查 CORS 配置是否过于宽松。

// Bad: Wildcard with credentials
headers.set("Access-Control-Allow-Origin", "*");
headers.set("Access-Control-Allow-Credentials", "true");

// Good: Specific origin
let allowedOrigins = ["https://app.example.com"];
let origin = req.headers.get("origin");
if (origin && allowedOrigins.includes(origin)) {
  headers.set("Access-Control-Allow-Origin", origin);
}
csrf-protection - @rules/csrf-protection.md

检查 CSRF 令牌和 SameSite Cookie。

// Bad: No CSRF protection
let cookies = parseCookies(req.headers.get("cookie"));
let session = await getSession(cookies.sessionId);

// Good: SameSite cookie + token validation
return new Response("OK", {
  headers: {
    "Set-Cookie": "session=abc; SameSite=Strict; Secure; HttpOnly",
  },
});
session-security - @rules/session-security.md

检查 Cookie 标志、JWT 问题和令牌存储。

// Bad: Insecure cookie
return new Response("OK", {
  headers: { "Set-Cookie": "session=abc123" },
});

// Good: Secure cookie with all flags
return new Response("OK", {
  headers: {
    "Set-Cookie":
      "session=abc123; Secure; HttpOnly; SameSite=Strict; Path=/; Max-Age=3600",
  },
});
API 与监控(MEDIUM-HIGH)
api-security - @rules/api-security.md

检查 REST API 漏洞和批量赋值问题。

// Bad: Mass assignment vulnerability
let userData = await req.json();
await db.user.update({ where: { id }, data: userData });

// Good: Explicitly allow fields
let { displayName, bio } = await req.json();
await db.user.update({
  where: { id },
  data: { displayName, bio }, // Only allowed fields
});
rate-limiting - @rules/rate-limiting.md

检查是否缺少速率限制和暴力破解防护。

// Bad: No rate limiting
async function login(req: Request): Promise<Response> {
  let { email, password } = await req.json();
  // Allows unlimited login attempts
}

// Good: Rate limiting
let ip = req.headers.get("x-forwarded-for");
let { success } = await ratelimit.limit(ip);
if (!success) {
  return new Response("Too many requests", { status: 429 });
}
logging-monitoring - @rules/logging-monitoring.md

检查日志记录是否不足,以及日志中是否包含敏感数据。

// Bad: Logging sensitive data
console.log("User login:", { email, password, ssn });

// Good: Log events without sensitive data
console.log("User login attempt", {
  email,
  ip: req.headers.get("x-forwarded-for"),
  timestamp: new Date().toISOString(),
});
vulnerable-dependencies - @rules/vulnerable-dependencies.md

检查过时的软件包和已知 CVE。

# Bad: No dependency checking
npm install

# Good: Regular audits
npm audit
npm audit fix

常见漏洞模式

以下是需要检查的模式的快速参考:

  • 未经验证的用户输入:req.json() → 立即使用
  • 缺少身份验证检查:未使用授权中间件的路由
  • 硬编码密钥:包含 "password"、"secret"、"key" 的字符串
  • SQL 注入:在查询中拼接字符串
  • XSS:dangerouslySetInnerHTML、.innerHTML
  • 弱加密算法:使用 md5、sha1 加密密码
  • 缺少安全标头:没有 CSP、HSTS 或安全标头
  • CORS 通配符:在带凭据的情况下使用 Access-Control-Allow-Origin: *
  • 不安全的 Cookie:缺少 Secure、HttpOnly、SameSite 标志
  • 路径遍历:未验证就将用户输入用于文件路径

严重性快速参考

立即修复(CRITICAL):

  • SQL/XSS/命令注入
  • 敏感端点缺少身份验证
  • 代码中存在硬编码密钥
  • 以明文存储密码
  • IDOR 漏洞

尽快修复(HIGH):

  • 缺少 CSRF 防护
  • 密码要求过弱
  • 缺少安全标头
  • CORS 权限过于宽松
  • 会话管理不安全

条件允许时修复(MEDIUM):

  • 缺少速率限制
  • 日志记录不完整
  • 依赖项过时(没有已知漏洞利用)
  • 非关键字段缺少输入验证

改进(LOW):

  • 缺少可选安全标头
  • 错误消息过于详细(非生产环境)
  • 加密参数不理想

评论

支持 Markdown