Token导航 LogoToken导航TokenDH.com
研究检索敏感数据github未标认证来源可访问许可证需确认审计通过

security-review安全审查

Agent Skill

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

总安装

504

周安装

21

GitHub Stars

1

下载量

168
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 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

简介

security-review 用于辅助安全审计、权限检查和常见漏洞排查。

  • 适合让 Agent 梳理敏感配置、分析鉴权逻辑或生成安全复核清单。
  • 使用时不能将工具输出直接当作最终结论,需人工复核关键操作。
  • 涉及密钥、令牌或生产系统时,应先确认最小权限和操作边界。
  • 通过 npx skills add 命令从指定 GitHub 仓库安装并使用。

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.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

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