Security Review Skill
Comprehensive security checklist for full-stack applications.
When to Use This Skill
- Reviewing API endpoints for vulnerabilities
- Auditing frontend code for XSS/CSRF risks
- Validating authentication and authorization patterns
- Checking data handling and storage security
- Pre-merge security review
- Reviewing AI-generated code for common pitfalls
- Evaluating MCP server configurations for security risks
Security Checklists
AI-Assisted Development Risks
| Check | Risk | What to Look For |
|---|---|---|
| Hallucinated Packages | High | AI-suggested packages that don't exist or have few downloads |
| Automation Bias | Medium | Complex logic accepted without thorough review |
| Context Poisoning | Medium | Suspicious comments that could manipulate AI suggestions |
| Prompt Injection Vectors | High | User input rendered in contexts AI might process (logs, error messages) |
| Outdated Patterns | Medium | Deprecated APIs or security anti-patterns from AI training data |
| Non-Compliant Patterns | Medium | AI generating code that ignores project conventions (e.g., passing req.body directly to Prisma) |
| Phantom Dependencies | High | AI adding import statements for packages not in package.json or that don't exist on npm |
| Insecure Defaults | Medium | AI using insecure defaults common in training data (e.g., cors({ origin: '*' }), disabled CSRF) |
| Over-Engineering (God Service) | Low | AI creating monolithic solutions with unnecessary complexity just because boilerplate is "free" |
AI-ism Detection Checklist
When reviewing AI-generated code, specifically check for these common LLM output patterns:
- Verify all imports: Run
npm ls <package>for any unfamiliar package. Check npm for download count (>10k weekly) and last publish date - Check for invented APIs: LLMs sometimes generate method calls that look plausible but don't exist (e.g.,
prisma.task.findFirstOrCreate()) - Scan for insecure defaults: Look for permissive CORS, disabled auth middleware,
anytypes masking validation gaps - Watch for training data leaks: Generic variable names, TODO comments from other projects, or boilerplate that doesn't match project conventions
- Validate error handling: AI often generates optimistic code paths without proper error handling or with catch blocks that swallow errors silently
MCP Server Security
| Check | Risk | What to Look For |
|---|---|---|
| Hardcoded Credentials | Critical | API keys or tokens in mcp.json instead of ${env:VAR} |
| HTTP Transport Exposure | High | HTTP servers on non-localhost without auth |
| Excessive Permissions | High | MCP tools with write/delete access when read-only would suffice |
| Missing Tool Approval | Medium | chat.mcp.autoApprove.enabled: true in settings |
| Unvetted Servers | Medium | Third-party MCP servers without source review |
API Endpoints (Express/Prisma)
| Check | Risk | What to Look For |
|---|---|---|
| Mass Assignment | High | req.body passed directly to Prisma create() or update() |
| SQL Injection | Critical | Raw queries with string interpolation |
| Missing Validation | Medium | No input validation before database operations |
| Broken Access Control | High | Missing ownership checks (e.g., user can edit any task) |
| Sensitive Data Exposure | Medium | Passwords, tokens, or PII in responses |
| Missing Rate Limiting | Medium | No protection against brute force |
Frontend (Vue/Pinia)
| Check | Risk | What to Look For |
|---|---|---|
| XSS | High | v-html with user-supplied content |
| Secrets in Code | Critical | API keys or tokens in frontend code |
| Insecure Storage | Medium | Sensitive data in localStorage |
| CSRF | Medium | State-changing GET requests |
Authentication & Authorization
| Check | Risk | What to Look For |
|---|---|---|
| Weak Tokens | Critical | Predictable session tokens or JWTs without proper signing |
| Missing Auth Checks | High | Routes without authentication middleware |
| Privilege Escalation | High | Role checks that can be bypassed |
| Session Management | Medium | Sessions that don't expire or rotate |
Data Handling
| Check | Risk | What to Look For |
|---|---|---|
| Unencrypted Secrets | Critical | Passwords stored in plain text |
| Logging Sensitive Data | Medium | PII or credentials in log output |
| Insecure Transmission | High | HTTP instead of HTTPS for sensitive data |
| Missing Input Sanitization | Medium | User input used without sanitization |
Output Format
When reporting security findings, use this structure:
## Security Review: [File/Feature Name]
### π΄ Critical Issues
- **[Issue Name]** at [file.ts#L42](file.ts#L42)
- **Risk:** Description of what could go wrong
- **Fix:** Recommended remediation
### π High Issues
- **[Issue Name]** at [file.ts#L15](file.ts#L15)
- **Risk:** Description of vulnerability
- **Fix:** Recommended remediation
### π‘ Medium Issues
- **[Issue Name]** at [file.ts#L88](file.ts#L88)
- **Risk:** Description of concern
- **Fix:** Recommended remediation
### π’ Low Issues / Recommendations
- Consider [improvement suggestion]
### β
Passed Checks
- Mass assignment protection β
- Input validation β
- Authentication checks β
Secure Patterns for This Project
Express Route Security
// β
Correct: Whitelist fields explicitly
const { title, description, priorityId } = req.body
await prisma.task.create({
data: { title, description, priorityId }
})
// β Wrong: Mass assignment vulnerability
await prisma.task.create({ data: req.body })
Vue Template Security
<!-- β
Correct: Text interpolation (auto-escaped) -->
<p>{{ userInput }}</p>
<!-- β Wrong: XSS vulnerability -->
<p v-html="userInput"></p>
Input Validation
// β
Correct: Validate before use
if (!title || typeof title !== 'string' || title.length > 200) {
return res.status(400).json({ error: 'Invalid title' })
}
// β Wrong: Trust user input
await prisma.task.create({ data: { title: req.body.title } })
AI-Generated Code Review
// β οΈ AI suggested this package - VERIFY before installing:
// 1. Check npm: https://www.npmjs.com/package/fast-csv-parser
// 2. Verify downloads (>10k weekly), maintainer, last update
// 3. Check for known vulnerabilities: npm audit
import { parse } from 'fast-csv-parser'
// β οΈ AI generated complex logic - REVIEW carefully:
// - Does this match requirements?
// - Are edge cases handled?
// - Is error handling complete?
MCP Configuration Security
// β
Correct: Use environment variable expansion
{
"env": {
"API_TOKEN": "${env:GITHUB_TOKEN}"
}
}
// β Wrong: Hardcoded credentials
{
"env": {
"API_TOKEN": "ghp_xxxxxxxxxxxx"
}
}
Reference Documentation
For secure implementation patterns and comprehensive security guidelines, see:
- Backend Routes Instructions β Secure Express/Prisma patterns
- Security Guide β AI attack surface and operational checklist
MCP Risk Scoring Framework
Use this quantitative model to evaluate MCP server and tool risks:
$$R_{total} = \sum_{tool=1}^{n} (A_{tool} \times S_{tool} \times D_{tool})$$
Scoring Factors
| Factor | Score | Description |
|---|---|---|
| A (Agency) | 0 | Read-only (e.g., read_file, list_tasks) |
| 0.5 | Creative/Generative (e.g., write_draft, create_issue) | |
| 1.0 | Destructive/Executive (e.g., delete_file, execute_terminal, drop_table) | |
| S (Source Trust) | 0 | Internal/Vetted (company-maintained, code reviewed) |
| 0.5 | Trusted vendor (Microsoft, GitHub, official integrations) | |
| 1.0 | Public/Unverified (third-party, no source review) | |
| D (Data Sensitivity) | 0 | Public data only |
| 0.5 | Internal data (non-sensitive business data) | |
| 1.0 | PII/Secrets/Core IP |
Risk Thresholds
| Score | Action |
|---|---|
| 0.0 - 0.25 | β Auto-approve eligible (read-only, trusted, public data) |
| 0.26 - 0.5 | β οΈ Requires per-session approval |
| 0.51 - 0.75 | πΆ Requires explicit user confirmation per action |
| 0.76 - 1.0 | π΄ Deny by policy; requires security team exception |
Capability-based overrides:
Even if a server's numeric score falls into the 0.0β0.25 "Auto-approve eligible" band, require at least per-session approval when:
- It can perform any non-read-only action (create/update/delete/execute/generate), or
- It can access internal, customer, or otherwise non-public data, or
- It is vendor-hosted and has broad access to your project or workspace.
These capability-based overrides ensure that powerful or data-sensitive integrations are never fully auto-approved, even with a low numeric risk score.
Example: Project MCP Servers
| Server | Agency | Source | Data | Risk Score | Recommendation |
|---|---|---|---|---|---|
| figma-desktop | 0 (read) | 0.5 (vendor) | 0 (public) | 0.0 | β Auto-approve eligible |
| atlassian | 0.5 (create) | 0.5 (vendor) | 0.5 (internal) | 0.125 | β οΈ Session approval (write + internal data β capability override) |
| playwright | 0.5 (execute) | 0.5 (vendor) | 0 (test data) | 0.0 | β οΈ Session approval (execute capabilities β capability override) |
| chrome-devtools | 0 (read) | 0.5 (vendor) | 0.5 (may see app data) | 0.0 | β οΈ Session approval (may access app data β capability override) |
| awesome-copilot | 0.5 (generate) | 0.5 (vendor) | 0 (public) | 0.0 | β οΈ Session approval (generate code/actions β capability override) |
