Token导航 LogoToken导航

Agent Skill · 研究检索

security-review(安全审查)

用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查。它适合让 Agent 梳理敏感配置、检查依赖风险、分析鉴权逻辑或生成安全复核清单。使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。

security-review 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 54,591。

总安装 504周安装 21GitHub Stars 1下载 168核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:security-review(安全审查)
来源仓库:https://github.com/oktsec/security-review
仓库路径:skills/security-review
安装命令:
npx skills add https://github.com/oktsec/security-review --skill security-review
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/oktsec/security-review --skill security-review

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

security-review 用于辅助安全审计、权限检查和常见漏洞排查。适合让 Agent 梳理敏感配置、分析鉴权逻辑或生成安全复核清单。使用时不能将工具输出直接当作最终结论,需人工复核关键操作。涉及密钥、令牌或生产系统时,应先确认最小权限和操作边界。

通过 npx skills add 命令从指定 GitHub 仓库安装并使用。

来源仓库内路径:skills/security-review

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/oktsec/security-review --skill security-review;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

security-review 怎么安装?

在终端执行 npx skills add https://github.com/oktsec/security-review --skill security-review。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

security-review 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

security-review 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

security-review 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

security-review 用的人多吗?

公开数据是累计安装 504 次,近一周安装 21 次,下载 168 次,GitHub 1 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

security-review 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
security-review

安全审查 · 本页

5041接触敏感数据未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Security Review

Security review for code built with LLMs. Auto-detects the stack, runs checks organized by severity, produces a graded report with exact fixes.

No questions. No setup. Read the project and review it.

Instructions

Phase 1: Detect

Read the project root. Detect everything automatically. Do NOT ask the user questions.

Stack detection - check for these files:

  • package.json → Node.js. Read it: check for next, express, fastify, hono, koa, nuxt, svelte, remix
  • requirements.txt / pyproject.toml / Pipfile → Python. Check for flask, django, fastapi, starlette
  • go.mod → Go. Check for gin, echo, chi, fiber, net/http
  • Cargo.toml → Rust
  • Gemfile → Ruby / Rails
  • composer.json → PHP / Laravel

Database - check deps and imports for: prisma, drizzle, knex, sequelize, typeorm, mongoose, sqlalchemy, gorm, diesel, ent

BaaS - check for: @supabase/supabase-js, firebase, firebase-admin, convex, appwrite. These have their own auth and access control rules that need separate checks

Auth - check deps for: next-auth, @auth/core, @clerk/nextjs, @clerk/clerk-sdk-node, better-auth, supabase, passport, lucia, jwt, bcrypt, argon2

OAuth providers - check for: passport-google, passport-github, @auth/google, next-auth providers, oauth2 client libraries

AI/LLM - check for: openai, @anthropic-ai/sdk, ai (Vercel AI SDK), langchain, llamaindex, @google/generative-ai, cohere-ai, replicate. Almost every SaaS has AI features now - these need their own security checks

Payments - check deps and code for: stripe, paddle, lemonsqueezy, paypal

File uploads - check for: multer, formidable, busboy, express-fileupload, python-multipart, uploadthing

Infra - check for: Dockerfile, docker-compose.yml, vercel.json, netlify.toml, fly.toml, wrangler.toml, railway.json, .github/workflows/

MCP - check for MCP config files in the project

Report a one-line summary of what you detected, then start scanning. Example:

Detected: Next.js 14 + Prisma + PostgreSQL, Stripe payments, NextAuth, Docker, GitHub Actions

Phase 2: Scan

Run these checks using Grep and Glob tools with the exact patterns below. Exclude node_modules, .git, vendor, dist, build, .next, __pycache__, venv, .venv from all searches.


CRITICAL: Secrets in code

Search for each pattern. Report file and line number for every match.

IMPORTANT: Credential redaction rule. When reporting secret findings, NEVER reproduce the full secret value in the output. Always redact: show only the first 4 characters followed by **** (e.g., sk-pr****, AKIA****, ghp_x****). In Before/After code blocks for secret findings, use the redacted form. This prevents accidental exfiltration of credentials through the report itself.

API keys:

PatternWhat
AKIA[0-9A-Z]{16}AWS access key
sk_live_[a-zA-Z0-9]{24,}Stripe live key
rk_live_[a-zA-Z0-9]{24,}Stripe restricted key
sk-proj-[a-zA-Z0-9\-_]{20,}OpenAI project key
sk-ant-[a-zA-Z0-9\-_]{80,}Anthropic key
sk-[a-zA-Z0-9]{48,}OpenAI legacy key (long format)
ghp_[a-zA-Z0-9]{36}GitHub PAT
gho_[a-zA-Z0-9]{36}GitHub OAuth
github_pat_[a-zA-Z0-9_]{80,}GitHub fine-grained PAT
glpat-[a-zA-Z0-9\-_]{20,}GitLab PAT
xoxb-[0-9]{10,}-[a-zA-Z0-9]+Slack bot token
xoxp-[0-9]{10,}-[a-zA-Z0-9]+Slack user token
SG\.[a-zA-Z0-9\-_]{22}\.[a-zA-Z0-9\-_]{22}SendGrid key
sq0atp-[a-zA-Z0-9\-_]{22}Square access token
AC[a-z0-9]{32}Twilio account SID (confirm: near auth_token or twilio import)
key-[a-zA-Z0-9]{32}Mailgun key (confirm: near mailgun import or config)

Private keys:

PatternWhat
`-----BEGIN (RSA\EC\DSA\OPENSSH) PRIVATE KEY`Private key in code
-----BEGIN PGP PRIVATE KEYPGP private key

Connection strings with credentials:

PatternWhat
`(postgres\postgresql\mysql\mongodb\+srv\mongodb):\/\/[^:\s]+:[^@\s]+@`Database connection string with embedded password
redis:\/\/:[^@\s]+@Redis with password
amqps?:\/\/[^:\s]+:[^@\s]+@RabbitMQ with password

Hardcoded secrets in assignments:

PatternWhat
`(password\passwd\secret\api_key\apiKey\api_secret\token\auth_token)\s*[:=]\s*['"][A-Za-z0-9\-_./+]{12,}['"]`Hardcoded secret value (12+ chars, not a placeholder)

Context rules - adjust severity based on location:

  • In *.test.*, *.spec.*, __tests__/, test/, fixtures/, testdata/, mock/: downgrade to INFO
  • In *.example, *.sample, *.template, README*, docs/: downgrade to INFO
  • If the value contains xxx, your-, TODO, CHANGE, example, placeholder, dummy, test, fake: downgrade to INFO
  • In .env that IS in .gitignore: downgrade to INFO (correctly handled)
  • In .env that is NOT in .gitignore: keep CRITICAL
  • In committed source code with real-looking values: keep CRITICAL

Then check.gitignore:

Read .gitignore. Verify these entries exist:

.env
.env.local
.env.*.local
*.pem
*.key

If .env is missing from .gitignore: CRITICAL finding on its own.

Then check git history for leaked secrets:

git log --all --oneline -- '.env' '.env.local' '*.pem' '*.key' 2>/dev/null | head -10

If any results: secrets may be in git history even if currently gitignored. CRITICAL. Tell the user they need to rotate those credentials - removing a file from git does not remove it from history.


HIGH: Injection vulnerabilities

SQL injection - string interpolation in queries:

PatternLanguageIssue
query\(.*\$\{JS/TSTemplate literal in SQL query
`query\(.*\+\s*(req\params\body\query\input\args\ctx)`JS/TSString concatenation with user input in SQL
execute\(f["']Pythonf-string in SQL execute
execute\(["'].*%s.*%\sPythonUnsafe % formatting in SQL (tuple args are safe, flag only % variable)
cursor\.execute\(.*\.format\(Pythonstr.format() in SQL
\.Raw\(.*fmt\.SprintfGoSprintf in raw SQL query
\.Exec\(.*\+\sGoString concat in Exec SQL call
\.Query\(.*\+\sGoString concat in Query SQL call
\.Where\(.*fmt\.SprintfGo (GORM)Sprintf in GORM Where

XSS - unescaped user content in HTML:

PatternFrameworkIssue
dangerouslySetInnerHTMLReactDirect HTML injection. Verify the source is sanitized (DOMPurify). If it renders user input: HIGH
innerHTML\s*=Vanilla JSDOM-based XSS
\.html\(jQueryHTML injection (verify source is user-controlled)
v-html=VueUnescaped HTML binding
`\safe`Django/Jinja2Auto-escaping disabled
\{\{\{.*\}\}\}Handlebars/MustacheUnescaped output
<%[-]?=EJSUnescaped output (verify source is sanitized)

Command injection:

PatternLanguageIssue
exec\(.*\$\{JS/TSTemplate literal in shell exec
exec\(.*\+JS/TSString concat in shell exec
child_process.*exec\(Node.jsShell exec (exec runs via shell; use execFile or spawn instead)
os\.system\(Pythonos.system always runs via shell (use subprocess with shell=False)
`subprocess\.(call\run\Popen)\(.*shell=True`PythonShell=True enables injection
exec\.Command\(.*\+GoString concat in command args

Path traversal:

PatternLanguageIssue
`path\.join\(.*req\.(params\query\body)`Node.jsUser input in file path without validation
`os\.path\.join\(.*request\.(GET\POST\args\form)`PythonUser input in file path
`filepath\.Join\(.*r\.(URL\Form\PathValue)`GoUser input in file path
sendFile\(.*req\.ExpressServing file based on user input
send_file\(.*request\.FlaskServing file based on user input

SSRF (Server-Side Request Forgery) - AI generates code that fetches user-provided URLs without validation. Attacker can read internal services, cloud metadata (169.254.169.254), or scan your network:

PatternLanguageIssue
`fetch\(.*req\.(params\query\body)`JS/TSUser-controlled URL in fetch
`axios\(.*req\.(params\query\body)`JS/TSUser-controlled URL in axios
axios\.get\(.*req\.JS/TSUser-controlled URL in axios.get
`requests\.(get\post)\(.*request\.(GET\POST\args\form\json)`PythonUser-controlled URL in requests
urllib\.request\.urlopen\(.*request\.PythonUser-controlled URL in urllib
`http\.Get\(.*r\.(URL\Form\PathValue)`GoUser-controlled URL in http.Get

If any found: verify the URL is validated against an allowlist of domains. Blocklisting localhost/127.0.0.1 alone is insufficient (bypassed with DNS rebinding, IPv6, decimal IPs).

Unsafe deserialization - AI uses serialization functions that execute arbitrary code when fed malicious input:

PatternLanguageIssue
pickle\.load\(PythonExecutes arbitrary code during deserialization. Never use on untrusted data
yaml\.load\( without Loader=SafeLoaderPythonCan execute arbitrary Python. Use yaml.safe_load()
`eval\(.*req\.(body\query\params)`JS/TSExecutes arbitrary code from user input
`eval\(.*request\.(GET\POST\json\form)`PythonExecutes arbitrary code from user input
new Function\(.*req\.JS/TSDynamic code execution from user input
unserialize\(PHPObject injection via deserialization

Open redirect - AI generates redirect code using user input. Attacker uses your domain for phishing (yourapp.com/redirect?url=evil.com):

PatternLanguageIssue
`res\.redirect\(.*req\.(params\query\body)`ExpressUser-controlled redirect URL
`redirect\(.*request\.(GET\POST\args)`PythonUser-controlled redirect URL
`http\.Redirect\(.*r\.(URL\Form)`GoUser-controlled redirect URL
window\.location\s*=\s*JS (client)Client-side redirect (verify source)

HIGH: Authentication and session security

Weak password hashing:

PatternIssueFix
createHash\(['"]md5['"]\)MD5 is crackable in secondsUse bcrypt or argon2
md5\(.*passwordMD5 on password inputUse bcrypt or argon2
`createHash\(['"]sha(1\256\512)['"]\)`SHA is fast, not a password hash (verify: used near password/user context)Use bcrypt or argon2
`hashlib\.(md5\sha1\sha256)\(.*password`Python: not a password hashUse bcrypt or argon2
`MessageDigest.*(MD5\SHA)`Java: not a password hash (verify: used near password context)Use BCrypt

Look for the CORRECT patterns too (bcrypt, argon2, scrypt, pbkdf2). If none found and the app has auth: HIGH.

Insecure randomness - AI uses Math.random() for things that need to be unpredictable:

PatternLanguageIssue
Math\.random\(\) near token, session, id, key, secret, nonceJS/TSPredictable output. Use crypto.randomUUID() or crypto.getRandomValues()
`random\.(random\randint\choice)\(` near token, secret, password, keyPythonPredictable. Use secrets.token_hex() or secrets.token_urlsafe()

JWT issues:

PatternIssue
jwt\.sign\(Search for all sign calls. If none include expiresIn or exp in payload: token never expires
algorithm.*['"]none['"]Algorithm none attack - accepts unsigned tokens
algorithms.*\[.*['"]none['"]Algorithm none in allowed list
verify.*falseSignature verification disabled (confirm: in JWT/auth context)

If jsonwebtoken is in deps, also grep for expiresIn. If zero matches in the entire codebase: HIGH (tokens never expire).

Cookie security:

Search for cookie-setting code. Check for:

FlagRequiredRisk if missing
httpOnly: trueYesJavaScript can steal session cookies via XSS
secure: trueYes in productionCookies sent over HTTP in cleartext
sameSite: 'strict' or 'lax'YesCSRF attacks

Rate limiting:

Check if any rate limiting exists on auth endpoints:

  • Node.js: search for express-rate-limit, rate-limit, @fastify/rate-limit in package.json
  • Python: search for slowapi, django-ratelimit, flask-limiter in deps
  • Go: search for rate limit middleware in router setup

If no rate limiting AND auth endpoints exist: HIGH. A login endpoint without rate limiting can be brute-forced.


HIGH: Database access control

Supabase without Row Level Security (RLS):

If Supabase detected, check for RLS:

  • Search for supabase.from( calls. If the app queries tables directly from the client, RLS must be enabled or any authenticated user can read/modify all rows
  • Check if a migrations/ or supabase/ directory exists with SQL files. Search for ALTER TABLE.*ENABLE ROW LEVEL SECURITY and CREATE POLICY. If tables exist without RLS policies: CRITICAL
  • Search for service_role key usage. The service role bypasses RLS - it must NEVER be exposed to the client/frontend
PatternIssue
service_roleSupabase service role key (bypasses all RLS - must only be in server-side code, never in client bundle)
SUPABASE_SERVICE_ROLEService role in env (verify: only used server-side)
supabase\.auth\.adminAdmin auth API (verify: only in server-side code)

Firebase without security rules:

If Firebase detected:

  • Check for firestore.rules or database.rules.json. If missing: CRITICAL (defaults may allow public read/write)
  • Search rules files for allow read, write: if true or allow read, write: if request.auth!= null without further conditions (any authenticated user can access everything)
PatternIssue
allow read, write: if trueFirebase rule allows public access - no auth required
allow read, write: if request.auth!= nullAny logged-in user can read/write all documents (need per-document rules with resource.data)

Mass assignment - AI passes raw request body to database create/update. User adds isAdmin: true or role: admin to the request:

PatternLanguageIssue
\.create\(req\.bodyJS/TS (ORM)Raw request body in create - user controls all fields
`\.create\(\*\*request\.(json\form\data)`Python (ORM)Raw request data in create
\.update\(req\.bodyJS/TS (ORM)Raw request body in update
Object\.assign\(.*req\.bodyJS/TSMerging raw request into object
\{\.\.\.req\.body\}JS/TSSpreading raw request body

CONDITIONAL: Next.js + Vercel (skip if not detected)

NEXT_PUBLIC_ env var exposure - Variables prefixed with NEXT_PUBLIC_ are bundled into the client JavaScript. AI frequently puts server-side secrets here:

PatternIssue
NEXT_PUBLIC_.*SECRETSecret exposed to browser
NEXT_PUBLIC_.*KEY that isn't a publishable keyVerify: Supabase anon key is OK, but service_role key is not
NEXT_PUBLIC_SUPABASE_SERVICE_ROLEService role key shipped to every browser
NEXT_PUBLIC_STRIPE_SECRETStripe secret key in client bundle
NEXT_PUBLIC_DATABASEDatabase credentials in client
NEXT_PUBLIC_.*TOKENToken exposed to browser (verify: is this a public token?)

Check .env* files and next.config.* for any NEXT_PUBLIC_ variable that holds a secret.

Server Actions and API routes without auth:

PatternIssue
"use server"Search all Server Action files. Verify each exported function checks auth before mutating data
`app/api/.*route\.(ts\js)`Check each API route for auth middleware. AI often creates API routes without getServerSession or equivalent
`export async function (GET\POST\PUT\DELETE)`Next.js route handler - verify auth check exists

Vercel deployment:

  • Check vercel.json for env vars in plaintext (should use Vercel dashboard, not config file)
  • Check if preview deployments have access to production secrets (common misconfiguration)

CONDITIONAL: Clerk auth (skip if not detected)
PatternIssue
CLERK_SECRET_KEY with NEXT_PUBLIC_ prefixSecret key exposed to client - CRITICAL
clerkMiddleware\(\) without createRouteMatcherMiddleware doesn't protect any routes by default. Must define protected routes
auth\(\)Search Server Components and Actions. Verify auth() is called before data access/mutations
API routes without auth() or getAuth()Unprotected API endpoint

If Clerk is detected: verify middleware.ts exists and uses createRouteMatcher to protect routes. Default Clerk middleware without route matching protects nothing.


CONDITIONAL: AI/LLM integration (skip if no AI deps detected)

API key exposure:

PatternIssue
NEXT_PUBLIC_OPENAIOpenAI key in client bundle
NEXT_PUBLIC_ANTHROPICAnthropic key in client bundle
openai.*api_key.*=.*['"]sk-Hardcoded OpenAI key
new OpenAI\(\{ without apiKey: process.envPossible hardcoded key in constructor

Prompt injection via user input - AI passes user input directly to LLM without sanitization:

PatternIssue
`messages.*role.*user.*content.*req\.(body\query\params)`Raw user input in LLM message
prompt.*\$\{.*req\.User input interpolated into prompt template
prompt.*\+.*req\.User input concatenated into prompt
generateText\(.*\$\{Vercel AI SDK with interpolated user input

If AI features exist: check that user input is never directly interpolated into system prompts. User input should go in the user message role, not concatenated into system/instruction text.

Missing rate limiting on AI endpoints:

  • AI endpoints are expensive. Search for rate limiting on routes that call LLM APIs
  • If no rate limiting on /api/ai, /api/chat, /api/generate, or similar: HIGH (attacker can run up your API bill)

CONDITIONAL: MongoDB Atlas (skip if not detected)
PatternIssue
mongodb\+srv:// with password in connection stringEmbedded credentials (use env var)
0\.0\.0\.0/0 in any MongoDB config or commentsNetwork access open to the entire internet
mongoose\.connect\( without auth optionsVerify auth is configured
No mongoose\.set\('strictQuery'May return unexpected fields

HIGH: Overly permissive configs

CORS wildcard:

PatternFrameworkIssue
cors\(\)ExpressDefaults to origin: * if called with no config object
Access-Control-Allow-Origin.*\*AnyWildcard CORS header
CORS\(app\)Flask-CORSAllows all origins if no origins= param
AllowAllOrigins:\s*trueGo gin-corsAllows all origins
allowedOrigins.*\*SpringAllows all origins
allowedOriginPatterns.*\*SpringAllows all origin patterns
CORS_ALLOW_ALL_ORIGINS\s*=\s*TrueDjangoAllows all origins

If CORS wildcard found, check if it's only in development config. If it's in production or the default config: HIGH.

Dangerous network binding:

PatternIssue
listen\(.*['"]0\.0\.0\.0['"]Binding to all interfaces (ok inside Docker, risky on bare metal)
host.*['"]0\.0\.0\.0['"]Service exposed to network (verify: intentional in container?)
bind.*['"]0\.0\.0\.0['"]Accessible from network

Debug mode in production:

PatternFrameworkIssue
DEBUG\s*=\s*TrueDjangoFull stack traces exposed (skip if in settings/dev.py or local_settings.py)
app\.debug\s*=\s*TrueFlaskDebug mode with interactive debugger
NODE_ENV.*developmentNode.jsFlag only in Dockerfile or docker-compose (dev mode in container)
enableDevTools.*trueVariousDev tools accessible in production
devtool.*trueVariousSource maps or debug tools enabled

Missing security headers:

Check if security headers are set. Search for helmet (Node.js), django-csp / django.middleware.security (Django), secure (Go).

If no security header middleware found and the app serves HTTP responses: MEDIUM.

Key headers to verify:

HeaderRisk if missing
Strict-Transport-SecurityBrowser allows HTTP connections (credentials sent in cleartext)
X-Frame-Options or frame-ancestors in CSPClickjacking - attacker embeds your app in an iframe
X-Content-Type-Options: nosniffBrowser MIME-sniffs responses (can execute uploaded files as scripts)
Content-Security-PolicyNo XSS mitigation at browser level

Exposed internals (manual checks, not pattern-based):

  1. Check if the static file server config serves dotfiles (.git exposure = full source code leak)
  2. Search error handlers for stack trace leaks: look for err.stack, traceback.format_exc(), debug.PrintStack() in response bodies
  3. Check if /api/ routes apply auth middleware. Search for route definitions without auth, protect, requireAuth, isAuthenticated middleware

MEDIUM: Dependencies

Run audit (only if the tool is available):

# Node.js (human-readable summary, not JSON)
npm audit --omit=dev 2>/dev/null

# Python
pip audit 2>/dev/null || pip-audit 2>/dev/null

# Go
govulncheck ./... 2>/dev/null

Report summary: X critical, Y high, Z moderate vulnerabilities.

Version pinning:

Check package.json dependencies (not devDependencies) for:

PatternIssue
"*"Completely unpinned - any version
"latest"Unpinned - resolves at install time
">="Open-ended range - no upper bound

Note: ^ and ~ in npm are normal (semver ranges). Only flag *, latest, and >=.

For requirements.txt: lines without == are unpinned. Flag them.


MEDIUM: Logging and monitoring

Check if the app has any security-relevant logging:

  • Search for login/auth event logging. If auth exists but zero log statements on failed logins: MEDIUM (can't detect brute force)
  • Search for error monitoring: sentry, bugsnag, datadog, newrelic, logtail in deps. If none and the app is production-ready: MEDIUM
  • If error handlers use console.log only (no structured logging, no external service): note as improvement

MEDIUM: Data exposure
PatternIssue
console\.log\(.*req\.bodyLogging full request body (may contain passwords)
console\.log\(.*request\.bodyLogging full request body (Python/Express)
console\.log\(.*passwordExplicitly logging passwords
print\(.*passwordExplicitly logging passwords (Python)
logger\.\w+\(.*passwordLogging passwords via logger
SELECT\s+\*Over-fetching (skip matches in migrations, seeds, and test files)
JSON\.stringify\(user\)May serialize password hash, internal fields to response
res\.json\(user\)Full user object in API response (should select specific fields)

CONDITIONAL: Third-party integrations (skip if no OAuth or external APIs detected)

OAuth state parameter - Without the state parameter, an attacker can trick a user into linking the attacker's account (CSRF on OAuth flow):

PatternIssue
passport\.authenticate\(Check if state: true or a custom state parameter is set. If not: HIGH
authorization_urlPython OAuth: check if state is generated and verified on callback
signIn\(NextAuth/Auth.js: verify CSRF protection is not disabled

For any OAuth flow: search for state near the authorization URL construction. If the word state does not appear near OAuth redirect logic: HIGH.

Webhook verification - Any incoming webhook (not just Stripe) must verify the sender's signature. Without it, anyone can POST fake events to your endpoint:

  • Search for webhook route handlers (/webhook, /api/webhook, /hook)
  • For each webhook endpoint, check if the handler verifies a signature header before processing
  • Common verification patterns: constructEvent, verify_signature, hmac, createHmac, webhook_secret
  • If a webhook endpoint processes data without ANY signature check: HIGH

External API calls without timeout - AI generates HTTP calls to external APIs without timeouts. A slow or dead API hangs your server.

Search for these call patterns, then check if a timeout is configured nearby:

Call patternLanguageTimeout to look for
fetch\(JS/TSAbortSignal.timeout or signal: in the options
axios\(JS/TStimeout: in the config object
`requests\.(get\post)\(`Pythontimeout= parameter
http\.Get\(Gocontext.WithTimeout or client.Timeout

If external API calls exist without any timeout: MEDIUM. One slow third-party API can take down your entire server.


CONDITIONAL: Payments (skip if no payment integration detected)
CheckWhat to search for
Webhook signature verificationSearch for constructEvent, webhook_construct_event, Webhook.construct_event. If Stripe is in deps but no webhook verification found: HIGH
Client-side amountSearch for amount/price in frontend POST requests to payment endpoints. Amount must be set server-side
Idempotency keysSearch for idempotencyKey, Idempotency-Key in payment creation. Missing = potential double charges

CONDITIONAL: File uploads (skip if no upload handling detected)
CheckWhat to look forIssue
File size limitSearch multer/formidable/busboy config for limits, maxFileSize, fileSizeLimit. If no limit set: HIGHAttacker uploads 10GB file, fills your disk
File type validationSearch for mimetype, fileFilter, content_type, allowed_extensions. If no type check: HIGHAttacker uploads executable, PHP shell, or HTML file (stored XSS)
Filename sanitizationSearch for path.basename, sanitize, originalname used directly in path.join. If original filename used as-is in file path: HIGHPath traversal via filename (../../etc/passwd)
Storage locationCheck if uploads go to a publicly accessible directory (public/, static/, uploads/ served by web server) without access controlDirect URL access to any uploaded file

CONDITIONAL: Docker (skip if no Dockerfile)
CheckPatternIssue
Running as rootDockerfile without USER instructionContainer runs as root
Secrets in build`ARG.*SECRET\PASSWORD\KEY\TOKEN` in DockerfileSecrets visible in image layers
Latest tagFROM.*:latestUnpinned base image
No.dockerignoreMissing .dockerignore file.env, .git, node_modules may be copied into image

Phase 3: Report

Output this exact structure. Be specific - reference actual files and line numbers.

## Security Report

**Project:** [name from package.json/go.mod/pyproject.toml]
**Stack:** [detected stack]
**Scanned:** [N files across M directories]
**Date:** [today]

### Score: [letter]

[One sentence explaining the score]

Scoring criteria (strict):

  • A: 0 critical, 0 high, ≤3 medium
  • B: 0 critical, 1-2 high, any medium
  • C: 0 critical, 3+ high
  • D: 1-2 critical findings
  • F: 3+ critical findings, or any active credential exposure in committed code

Then list findings grouped by severity. For EACH finding:

**[N]. [Title]** `[SEVERITY]`
📍 `file/path.js:42`
[One sentence: what it is and what an attacker can do with it]

Before:
‎```[lang]
[insecure code from their file - REDACT any secret values: show first 4 chars + ****]
‎```

After:
‎```[lang]
[secure replacement - use environment variable references, never actual secret values]
‎```

Redaction reminder: In Before/After blocks, never reproduce real API keys, passwords, tokens, or connection string credentials. Always redact secret values (e.g., "sk-pr****" or process.env.API_KEY). The goal is to show the code pattern, not expose the secret.

If the fix needs a package install, include the install command before the code fix.

After all findings, add:

### What's solid
- [2-3 specific things the codebase does well. Be genuine, not filler.]

### Top 3 actions
1. [Highest impact fix. One sentence + the command or code change.]
2. [Second priority.]
3. [Third priority.]

Examples

Example 1: "I built this SaaS with Cursor, is it secure?"

  1. Detect: Next.js 14 + Supabase + Stripe + Vercel
  2. Scan all categories. Focus on: Supabase RLS, Stripe webhook verification, secrets in .env
  3. Report: Score D - service_role key in client code, no RLS on 3 tables, Stripe webhook unverified
  4. Top 3: move service_role to server, enable RLS, add webhook signature check

Example 2: "Security review before launch"

  1. Detect stack, prioritize: secrets first, auth second, payments third
  2. Scan production config vs dev config - verify debug is off, CORS is scoped, security headers exist
  3. Report with quick wins section first for pre-launch fixes

Example 3: Clean project

  1. Detect and scan all categories
  2. Report: Score A - no findings. List what the codebase does well

Common Issues

Large codebases: Prioritize by severity - secrets first (biggest immediate risk), then auth, then payments. Don't try to scan everything in one pass. Skip node_modules, vendor, build artifacts.

Many false positives on hardcoded secrets: Apply context rules strictly. Test files, example configs, and placeholder values are INFO, not CRITICAL. If unsure, include the finding but mark it as "verify manually".

npm audit / pip audit not available: Skip the dependency audit command. Report that the tool wasn't available and recommend the user run it manually.

Project uses a framework not listed: Apply the general patterns (secrets, injection, auth) even if framework-specific patterns don't match. The core checks work across any stack.

Re-runs after fixes: When the user runs the skill again after applying fixes, scan the CURRENT filesystem state (not git history). Specifically:

  1. Read the actual files on disk, not cached or previous results. The user may have fixed issues without committing.
  2. For each check, verify the fix is actually applied by reading the current file content.
  3. Do NOT report the same finding if the code has been changed. If the vulnerable pattern is no longer present in the file, it's fixed.
  4. DO report findings in OTHER files or endpoints that weren't covered in the previous run. Be explicit: "This is a new finding not reported in the previous run."
  5. If the score improved, say so: "Score improved from D to B. 3 issues remain."

Consistency across runs: The goal is deterministic results. To achieve this:

  1. Always scan ALL files matching the patterns, not a sample. Don't stop after finding N issues.
  2. Report ALL findings, not just the first N. The user needs to know the full scope.
  3. When reporting, group by file so the user can work through fixes file by file.
  4. If the project is too large to scan completely in one pass, say so and recommend scanning by directory: /security-review src/api/ then /security-review src/components/

Phase 4: Fix mode

After presenting the report, ask the user:

"Want me to fix these issues? I can go through them one by one."

If the user says yes:

  1. Work through findings from highest severity to lowest
  2. For each finding, show what you're about to change and apply the fix
  3. Skip findings that require external action (e.g., rotating leaked keys, enabling RLS in Supabase dashboard)
  4. After all fixes are applied, re-run the checks on the modified files to confirm the issues are resolved
  5. Report what was fixed and what still needs manual attention

If the user says no or doesn't respond, end with the report.

Phase 5: Next steps

If the project uses MCP servers or AI agents, suggest the user look into auditing those configurations separately.

平台分布

Claude

33.13%
按下载量换算56

Codex

33.02%
按下载量换算55

Cursor

17.94%
按下载量换算30

Gemini CLI

9.39%
按下载量换算16

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills