owasp-security-check by sergiodxa/agent-skills
npx skills add https://github.com/sergiodxa/agent-skills --skill owasp-security-check针对 Web 应用程序和 REST API 的全面安全审计模式。包含 5 大类共 20 条规则,涵盖 OWASP Top 10 和常见的 Web 漏洞。
在以下情况使用此技能:
按优先级顺序处理各个类别:
按以下格式记录发现:
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
检查是否存在缺少授权、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));
}
检查是否存在弱身份验证、缺少 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;
}
检查是否存在弱加密、明文存储、不良哈希算法。
// Bad: MD5 for passwords
let hash = crypto.createHash("md5").update(password).digest("hex");
// Good: bcrypt with salt
let hash = await bcrypt(password, 12);
检查日志/响应中是否存在 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,
}),
);
检查是否存在未签名的数据、不安全的反序列化。
// 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);
检查是否存在硬编码的密钥、暴露的环境变量。
// 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");
检查是否存在 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 } });
检查是否存在未经验证的 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 });
}
检查是否存在无限制的上传、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 });
}
检查是否存在开放重定向、未经验证的重定向 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("/");
}
检查架构中是否存在安全反模式。
// 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");
检查是否存在默认配置、调试模式、错误处理问题。
// 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 });
}
检查是否存在 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 配置。
// 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 令牌、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",
},
});
检查是否存在 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",
},
});
检查是否存在 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
});
检查是否存在缺少速率限制、暴力破解防护。
// 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 });
}
检查是否存在日志记录不足、日志中包含敏感数据。
// 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(),
});
检查是否存在过时的包、已知的 CVE。
# Bad: No dependency checking
npm install
# Good: Regular audits
npm audit
npm audit fix
快速参考需要查找的模式:
req.json() → 立即使用dangerouslySetInnerHTML, .innerHTMLmd5、sha1Access-Control-Allow-Origin: * 与凭据一起使用立即修复 (CRITICAL):
尽快修复 (HIGH):
在可能时修复 (MEDIUM):
改进 (LOW):
每周安装量
480
代码仓库
GitHub 星标数
79
首次出现
2026年2月1日
安全审计
安装于
opencode441
codex423
gemini-cli417
cursor398
github-copilot397
claude-code357
Comprehensive security audit patterns for web applications and REST APIs. Contains 20 rules across 5 categories covering OWASP Top 10 and common web vulnerabilities.
Use this skill when:
Work through categories by priority:
Format findings as:
Check for missing authorization, IDOR, privilege escalation.
// 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));
}
Check for weak authentication, missing MFA, session issues.
// 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;
}
Check for weak encryption, plaintext storage, bad hashing.
// Bad: MD5 for passwords
let hash = crypto.createHash("md5").update(password).digest("hex");
// Good: bcrypt with salt
let hash = await bcrypt(password, 12);
Check for PII in logs/responses, error messages leaking info.
// 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,
}),
);
Check for unsigned data, insecure deserialization.
// 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);
Check for hardcoded secrets, exposed env vars.
// 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");
Check for SQL, XSS, NoSQL, Command, Path Traversal injection.
// Bad: SQL injection
let query = `SELECT * FROM users WHERE email = '${email}'`;
// Good: Parameterized query
let user = await db.user.findUnique({ where: { email } });
Check for unvalidated URLs, internal network access.
// 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 });
}
Check for unrestricted uploads, MIME validation.
// 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 });
}
Check for open redirects, unvalidated redirect URLs.
// 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("/");
}
Check for security anti-patterns in architecture.
// 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");
Check for default configs, debug mode, error handling.
// 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 });
}
Check for CSP, HSTS, X-Frame-Options, etc.
// 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",
},
});
Check for overly permissive 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);
}
Check for CSRF tokens, SameSite cookies.
// 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",
},
});
Check for cookie flags, JWT issues, token storage.
// 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",
},
});
Check for REST API vulnerabilities, mass assignment.
// 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
});
Check for missing rate limits, brute force prevention.
// 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 });
}
Check for insufficient logging, sensitive data in logs.
// 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(),
});
Check for outdated packages, known CVEs.
# Bad: No dependency checking
npm install
# Good: Regular audits
npm audit
npm audit fix
Quick reference of patterns to look for:
req.json() → immediate usedangerouslySetInnerHTML, .innerHTMLmd5, sha1 for passwordsAccess-Control-Allow-Origin: * with credentialsFix Immediately (CRITICAL):
Fix Soon (HIGH):
Fix When Possible (MEDIUM):
Improve (LOW):
Weekly Installs
480
Repository
GitHub Stars
79
First Seen
Feb 1, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode441
codex423
gemini-cli417
cursor398
github-copilot397
claude-code357
OpenClaw技能安全审计指南:skill-vetter工具详解与安装前安全检查
12,200 周安装
wacli - WhatsApp 命令行工具:安全发送消息、搜索历史记录与同步管理
372 周安装
React Native Reanimated + Skia 动画性能优化指南:提升帧率与流畅度
373 周安装
React前端开发指南:Suspense数据获取、懒加载与性能优化最佳实践
373 周安装
Lark Mail CLI 使用指南:邮件管理、安全规则与自动化工作流
7,100 周安装
OpenAPI 转 TypeScript 工具 - 自动生成 API 接口与类型守卫
563 周安装
Rust Unsafe代码检查器 - 安全使用Unsafe Rust的完整指南与最佳实践
566 周安装