security-audit — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited security-audit (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Security vulnerabilities are invisible until exploited. This skill provides a systematic approach to finding them before attackers do.
Core principle: ASSUME BREACH. Review every input, every output, every boundary.
Iron Law:
NO SECURITY REVIEW WITHOUT THREAT MODELING FIRSTBefore reviewing any code:
Work through each category systematically:
#### A01: Broken Access Control
- [ ] Every endpoint checks authentication
- [ ] Authorization verified per-resource, not just per-route
- [ ] IDOR: Can user A access user B's data by changing ID?
- [ ] Admin routes protected from regular users
- [ ] CORS policy restricts allowed origins#### A02: Cryptographic Failures
- [ ] No plaintext passwords stored
- [ ] Sensitive data encrypted at rest (PII, tokens, keys)
- [ ] TLS enforced for all connections
- [ ] Weak algorithms absent (MD5, SHA1 for passwords, DES)
- [ ] Secrets not in code, logs, or URLs#### A03: Injection
-- ❌ SQL Injection vulnerable
db.query(`SELECT * FROM users WHERE id = ${userId}`);
-- ✅ Parameterized
db.query('SELECT * FROM users WHERE id = ?', [userId]);// ❌ Command Injection
exec(`ls ${userInput}`);
// ✅ Safe
execFile('ls', [userInput]);// ❌ XSS
element.innerHTML = userInput;
// ✅ Safe
element.textContent = userInput;#### A04: Insecure Design
- [ ] Rate limiting on sensitive endpoints (login, password reset)
- [ ] Account lockout after failed attempts
- [ ] Password reset tokens expire (< 15 minutes)
- [ ] Sensitive operations require re-authentication#### A05: Security Misconfiguration
- [ ] Debug mode disabled in production
- [ ] Default credentials changed
- [ ] Unnecessary features/endpoints disabled
- [ ] Security headers present (CSP, HSTS, X-Frame-Options)
- [ ] Error messages don't expose stack traces to users#### A06: Vulnerable Components
# Check for known CVEs
npm audit
yarn audit
# Check for outdated packages with vulnerabilities
npx audit-ci --moderate#### A07: Authentication Failures
- [ ] Session IDs invalidated on logout
- [ ] JWT secrets sufficiently random (>= 256 bits)
- [ ] JWT expiry set appropriately (access: minutes, refresh: days)
- [ ] Brute force protection on login
- [ ] Multi-factor authentication available for sensitive actions#### A08: Software Integrity Failures
- [ ] Dependencies pinned to exact versions
- [ ] Subresource integrity (SRI) for CDN assets
- [ ] CI/CD pipeline secured (no untrusted code execution)
- [ ] Package signatures verified where possible#### A09: Logging Failures
- [ ] Authentication events logged (success + failure)
- [ ] Authorization failures logged
- [ ] No sensitive data (passwords, tokens, PII) in logs
- [ ] Log tampering prevented
- [ ] Alerts set for suspicious patterns#### A10: Server-Side Request Forgery (SSRF)
- [ ] User-supplied URLs validated against allowlist
- [ ] Internal network addresses blocked from user input
- [ ] DNS rebinding protection# Scan for hardcoded secrets
grep -rn "password\|secret\|token\|api_key\|apikey\|private_key" \
--include="*.ts" --include="*.js" --include="*.env*" \
--exclude-dir=node_modules .
# Check .gitignore covers sensitive files
cat .gitignore | grep -E "\.env|\.key|credentials"
# Verify no secrets in git history
git log --all --full-history -- "*.env" "*.key" "credentials*"Common secret patterns to find:
❌ const API_KEY = "sk-abc123..."
❌ password: "admin123"
❌ Authorization: "Bearer eyJ..." (hardcoded)
❌ connectionString = "mongodb://user:pass@host"
✅ const API_KEY = process.env.API_KEY
✅ password: process.env.DB_PASSWORDFor MCP servers using SSE/HTTP transport:
// ❌ No authentication
app.use('/sse', sseHandler);
// ✅ Bearer token validation
app.use('/sse', (req, res, next) => {
const token = req.headers.authorization?.replace('Bearer ', '');
if (process.env.MCP_SSE_TOKEN && token !== process.env.MCP_SSE_TOKEN) {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
});- [ ] SSE endpoint authenticates when MCP_SSE_TOKEN is set
- [ ] CORS configured for trusted origins only
- [ ] Rate limiting on MCP tool calls
- [ ] Input validation on all tool parameters
- [ ] No sensitive data in MCP resource URIs| Thought | Reality |
|---|---|
| "We're not a target" | Every internet-facing system is a target |
| "This is internal only" | Insider threats are real; internal ≠ trusted |
| "The framework handles it" | Frameworks have defaults that must be configured |
| "We'll add security later" | Retrofitting security costs 10× more |
| "Tests don't cover security" | Security requires dedicated review, not just tests |
| Category | Check | Tool |
|---|---|---|
| Dependencies | CVE scan | npm audit |
| Secrets | Hardcoded creds | grep + git-secrets |
| Injection | SQL, XSS, Command | Manual + ESLint |
| Auth | JWT, sessions | Manual review |
| Headers | CSP, HSTS | securityheaders.com |
| OWASP | Top 10 | ZAP, Burp Suite |
Document findings as:
## Security Audit Report — YYYY-MM-DD
### Critical (fix before deploy)
- [ ] SQL injection in /api/users endpoint (line 42, users.service.ts)
### High (fix within 24h)
- [ ] JWT secret too short (< 256 bits)
### Medium (fix this sprint)
- [ ] Missing rate limiting on /auth/login
### Low (backlog)
- [ ] Verbose error messages in development mode
### Passed Checks
- [x] No hardcoded secrets found
- [x] All endpoints require authentication~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.