brainstorming
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).
audit-securityAudit and fix app code against OWASP (injection, headers, dependencies). Use when "review security" or "check vulnerabilities". Auth gates → audit-auth-flows. Plan-only → plan-security-audit. RLS → plan-rls-audit. LLM → audit-llm-security.
Independent GitHub snapshot · Automated classification · Original documentation governs
Degree of freedom: MIXED — Steps 0–4 judgment [HIGH freedom];
dependency and secret scans [LOW freedom — run exactly]. Never write
exploit PoCs.
Audit-and-fix exception. May fix inline. Plan-only burndown →
plan-security-audit. When fixing inline: patch the evidenced sink only, in place; unrelated weaknesses you notice go in the report as findings, not fixes. Add a test only where the repo already keeps security tests or the task asks. Auth behavior, RLS, secrets rotation, payments, and migrations stay STOP-and-confirm.
OWASP static review (injection, headers, deps). Session / route×gate /
getSession() → audit-auth-flows. Next.js 16: grep middleware.ts and
proxy.ts — a route gate can live in either file, and the proxy layer has its own bypass class.
file:line)Observe:
GET /documents/:idloads by id only (api/docs/route.ts:18). Interpret: any caller who can hit the route reads another user's doc. Classify: IDOR. Severity: Critical. Finding: IDOR |/documents/:id| adduserIdpredicate. Matcher /getSession()on that route →audit-auth-flows, not this checklist.
Before auditing, discover the tech stack and attack surface:
package.json / requirements.txt / go.mod to identify:Fetch current OWASP and security best practices for the detected stack:
firecrawl:firecrawl_search
{
"query": "<framework> security best practices OWASP <current year>",
"limit": 5,
"sources": [{ "type": "web" }]
}
Scrape the OWASP Top 10 for the relevant platform:
firecrawl:firecrawl_scrape
{
"url": "https://owasp.org/Top10/",
"formats": ["markdown"],
"onlyMainContent": true
}
Also check for known CVEs in dependencies:
firecrawl:firecrawl_search
{
"query": "<package-name> CVE vulnerability <current year>",
"limit": 5,
"sources": [{ "type": "web" }]
}
If Sentry is configured, check for security-related production errors:
sentry:search_issues
{
"organizationSlug": "<ORG_SLUG>",
"query": "401 unauthorized OR 403 forbidden OR CORS OR CSP violation in last 30 days",
"projectSlugOrId": "<PROJECT_SLUG>",
"regionUrl": "<REGION_URL>",
"limit": 20
}
Patterns that indicate security findings:
eval(), Function(), innerHTML with user inputdangerouslySetInnerHTML without DOMPurifytype="password" and autocomplete="new-password"Strict-Transport-Security (HSTS) with long max-ageContent-Security-Policy (CSP) configured (not just default-src *)X-Content-Type-Options: nosniffX-Frame-Options: DENY or SAMEORIGINReferrer-Policy: strict-origin-when-cross-origin or stricterPermissions-Policy restricting unnecessary browser featuresAccess-Control-Allow-Origin is NOT * for authenticated endpointsHttpOnly, Secure, SameSite=Strict (or Lax)npm audit # Node.js
pip-audit # Python
cargo audit # Rust
govulncheck ./... # Go
bundle audit # Ruby
package-lock.json, yarn.lock, pnpm-lock.yaml)Grep for the sinks, then read each hit in context:
`SELECT … ${, + userId +); parameterized or ORM calls passdangerouslySetInnerHTML / innerHTML fed user input without DOMPurify.sanitizereq.params.id with no owner predicate (userId: req.user.id) on the queryres.json(user)-style whole-record responses instead of an explicit field pickSearch the codebase for potential leaked secrets. Patterns to look for:
api_key, apiKey, secret, password, token, credentials, private_keysk-, pk-, ghp_, gho_, xox[bpsa]-, AKIA-----BEGIN (RSA|EC|OPENSSH) PRIVATE KEY-----.env, .env.local, .env.production
*.pem, *.key, *.p12
credentials.json, service-account.json
.sentryclirc (if it contains auth tokens)
import { z } from 'zod';
const envSchema = z.object({
DATABASE_URL: z.string().url(),
API_KEY: z.string().min(1),
JWT_SECRET: z.string().min(32),
SENTRY_DSN: z.string().url().optional(),
});
const env = envSchema.parse(process.env);
file:line or audit output, not "this might be injectable"getSession → audit-auth-flows; RLS → plan-rls-audit; LLM → audit-llm-security## Security Audit: [Project Name]
### Tech Stack
- Framework: [name + version]
- Auth: [library + pattern]
- Database: [ORM + provider]
- Security packages: [list]
### Critical Issues (must fix)
| # | Category | Finding | File | Recommendation |
|---|----------|---------|------|----------------|
| 1 | Auth | JWT secret hardcoded | config.ts:12 | Move to env var |
### High Risk (should fix soon)
| # | Category | Finding | File | Recommendation |
|---|----------|---------|------|----------------|
### Medium Risk (improve when possible)
| # | Category | Finding | File | Recommendation |
|---|----------|---------|------|----------------|
### Passed Checks
- [list of security areas that are properly implemented]
### Dependencies
- Critical CVEs: [count] — [details]
- High CVEs: [count]
- Outdated packages: [count]
### Research Sources
- [URL] — [what it confirmed or revealed]
Session / route×gate / getSession() findings belong on audit-auth-flows,
not in this OWASP checklist.