@telelabsai/ship 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/reviewer.md +47 -0
- package/.claude/hooks/git-safety.cjs +14 -22
- package/.claude/rules/code-quality.md +15 -0
- package/.claude/rules/security.md +10 -0
- package/.claude/shared/secret-patterns.json +62 -0
- package/.claude/skills/ship-review/SKILL.md +74 -0
- package/.claude/skills/ship-review/references/output-format.md +62 -0
- package/.claude/skills/ship-review/references/review-categories.md +169 -0
- package/.claude/skills/ship-review/references/severity-levels.md +49 -0
- package/.claude/skills/ship-secure/SKILL.md +60 -0
- package/.claude/skills/ship-secure/references/dependency-audit.md +71 -0
- package/.claude/skills/ship-secure/references/owasp-checks.md +197 -0
- package/.claude/skills/ship-secure/references/secret-patterns.md +50 -0
- package/.claude/skills/ship-test/SKILL.md +85 -0
- package/.claude/skills/ship-test/references/coverage-analysis.md +70 -0
- package/.claude/skills/ship-test/references/output-format.md +71 -0
- package/.claude/skills/ship-test/references/test-workflow.md +47 -0
- package/.claude/skills/ship-version/SKILL.md +4 -0
- package/.claude/skills/ship-version/references/safety-protocols.md +10 -16
- package/LICENSE +21 -0
- package/README.md +102 -11
- package/cli/bin.js +18 -1
- package/cli/commands/auth.js +141 -0
- package/cli/commands/init.js +37 -6
- package/cli/commands/sync.js +142 -0
- package/git-hooks/pre-commit.cjs +143 -0
- package/package.json +3 -2
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reviewer
|
|
3
|
+
description: "Use this agent for code review, test analysis, and security scanning. Handles large diffs and verbose output in isolated context. Spawns for ship-review, ship-test, and ship-secure skills."
|
|
4
|
+
model: sonnet
|
|
5
|
+
tools: Bash, Read, Glob, Grep, Edit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a senior code reviewer, test analyst, and security auditor. You analyze codebases with precision and report findings concisely.
|
|
9
|
+
|
|
10
|
+
Activate the relevant skill by reading its SKILL.md and references:
|
|
11
|
+
- Code review: `.claude/skills/ship-review/SKILL.md`
|
|
12
|
+
- Test analysis: `.claude/skills/ship-test/SKILL.md`
|
|
13
|
+
- Security scan: `.claude/skills/ship-secure/SKILL.md`
|
|
14
|
+
|
|
15
|
+
## Core Principles
|
|
16
|
+
|
|
17
|
+
- Never report false positives. If unsure, mark as "Needs verification"
|
|
18
|
+
- Always include file path and line number for every finding
|
|
19
|
+
- Prioritize findings by impact, not alphabetically
|
|
20
|
+
- Explain WHY something is a problem, not just WHAT
|
|
21
|
+
- Suggest a fix for every finding
|
|
22
|
+
- Respect the codebase's existing patterns before suggesting changes
|
|
23
|
+
|
|
24
|
+
## Severity Levels
|
|
25
|
+
|
|
26
|
+
| Level | Meaning | CI behavior |
|
|
27
|
+
|-------|---------|-------------|
|
|
28
|
+
| Critical | Must fix. Security holes, data loss, broken logic | Blocks merge |
|
|
29
|
+
| Warning | Should fix. Performance, error handling, testing gaps | Warns |
|
|
30
|
+
| Suggestion | Nice to have. Naming, style, minor improvements | Info only |
|
|
31
|
+
|
|
32
|
+
## Output Format
|
|
33
|
+
|
|
34
|
+
Always end with a structured summary:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Files reviewed: N
|
|
38
|
+
Critical: N | Warning: N | Suggestion: N
|
|
39
|
+
Verdict: PASS or FAIL (FAIL if any critical)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## CI Mode
|
|
43
|
+
|
|
44
|
+
When `--ci` flag is present:
|
|
45
|
+
- Output only the structured report (no conversational text)
|
|
46
|
+
- Exit with status in verdict (PASS/FAIL)
|
|
47
|
+
- Format output as markdown suitable for PR comments
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* PreToolUse hook — blocks dangerous git operations before they execute.
|
|
3
|
+
* Reads secret patterns from shared/secret-patterns.json (single source of truth).
|
|
3
4
|
*
|
|
4
5
|
* Exit 0 = allow the tool call
|
|
5
6
|
* Exit 2 = block the tool call (stdout = reason shown to Claude)
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
9
11
|
|
|
10
12
|
let input;
|
|
11
13
|
try {
|
|
12
14
|
input = JSON.parse(fs.readFileSync('/dev/stdin', 'utf8'));
|
|
13
15
|
} catch {
|
|
14
|
-
process.exit(0);
|
|
16
|
+
process.exit(0);
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
const cmd = (input.tool_input && input.tool_input.command) || '';
|
|
20
|
+
const patterns = JSON.parse(
|
|
21
|
+
fs.readFileSync(path.join(__dirname, '..', 'shared', 'secret-patterns.json'), 'utf8')
|
|
22
|
+
);
|
|
18
23
|
|
|
19
24
|
// --- Block force push ---
|
|
20
25
|
if (/push\s+.*(-f|--force)(?!\S)/.test(cmd) && !cmd.includes('--force-with-lease')) {
|
|
@@ -22,36 +27,23 @@ if (/push\s+.*(-f|--force)(?!\S)/.test(cmd) && !cmd.includes('--force-with-lease
|
|
|
22
27
|
process.exit(2);
|
|
23
28
|
}
|
|
24
29
|
|
|
25
|
-
// --- Block push to protected branches without confirmation ---
|
|
26
|
-
const protectedPush = /push\s+.*\b(main|master|production|prod)\b/.test(cmd);
|
|
27
|
-
if (protectedPush && !cmd.includes('--force-with-lease')) {
|
|
28
|
-
// Allow regular push to main, but block force variants
|
|
29
|
-
// The rule file handles the "ask user" part for regular pushes
|
|
30
|
-
}
|
|
31
|
-
|
|
32
30
|
// --- Block staging sensitive files ---
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
/git\s+add\s+.*secrets?\./,
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
for (const pattern of sensitivePatterns) {
|
|
42
|
-
if (pattern.test(cmd)) {
|
|
43
|
-
console.log('BLOCKED: Cannot stage sensitive files (.env, credentials, keys). Add to .gitignore instead.');
|
|
31
|
+
for (const file of patterns.dangerousFiles) {
|
|
32
|
+
const escaped = file.replace(/\./g, '\\.').replace(/\*/g, '[^\\s]*');
|
|
33
|
+
const regex = new RegExp(`git\\s+add\\s+.*${escaped}`);
|
|
34
|
+
if (regex.test(cmd)) {
|
|
35
|
+
console.log(`BLOCKED: Cannot stage sensitive file matching "${file}". Add to .gitignore instead.`);
|
|
44
36
|
process.exit(2);
|
|
45
37
|
}
|
|
46
38
|
}
|
|
47
39
|
|
|
48
|
-
// --- Block git add -A / git add .
|
|
40
|
+
// --- Block git add -A / git add . ---
|
|
49
41
|
if (/git\s+add\s+(-A|--all|\.)(\s|$)/.test(cmd)) {
|
|
50
|
-
console.log('BLOCKED: Use specific file names instead of "git add ." or "git add -A" to avoid staging secrets
|
|
42
|
+
console.log('BLOCKED: Use specific file names instead of "git add ." or "git add -A" to avoid staging secrets.');
|
|
51
43
|
process.exit(2);
|
|
52
44
|
}
|
|
53
45
|
|
|
54
|
-
// --- Block destructive resets
|
|
46
|
+
// --- Block destructive resets ---
|
|
55
47
|
if (/git\s+reset\s+--hard/.test(cmd)) {
|
|
56
48
|
console.log('BLOCKED: "git reset --hard" discards all uncommitted changes. Ask the user to confirm first.');
|
|
57
49
|
process.exit(2);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Code Quality
|
|
2
|
+
|
|
3
|
+
Quick reminders (detailed checks in `.claude/skills/ship-review/references/review-categories.md`):
|
|
4
|
+
|
|
5
|
+
- No N+1 queries, missing indexes, or unbounded queries
|
|
6
|
+
- No race conditions in async code
|
|
7
|
+
- No memory leaks (uncleaned listeners, intervals, subscriptions)
|
|
8
|
+
- Validate error handling on all external calls (APIs, DB, file I/O)
|
|
9
|
+
- Consistent API response format across endpoints
|
|
10
|
+
- No nested loops over large datasets without justification
|
|
11
|
+
- Use caching on repeated expensive operations
|
|
12
|
+
- Validate input at system boundaries
|
|
13
|
+
- Use idempotency keys on payment operations
|
|
14
|
+
- Validate webhook signatures on incoming webhooks
|
|
15
|
+
- Use circuit breakers and timeouts on third-party API calls
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
- Never hardcode secrets, API keys, passwords, or tokens in source code
|
|
4
|
+
- Never use string concatenation in SQL/NoSQL queries (use parameterized queries)
|
|
5
|
+
- Never trust user input (validate and sanitize at all entry points)
|
|
6
|
+
- Ensure all endpoints have authentication and authorization checks
|
|
7
|
+
- Ensure sensitive data is not logged (passwords, tokens, PII)
|
|
8
|
+
- Ensure cookies use httpOnly, secure, and sameSite flags
|
|
9
|
+
- Ensure JWT tokens have expiration
|
|
10
|
+
- Secret patterns defined in .claude/shared/secret-patterns.json
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Single source of truth for secret detection. Used by hooks, skills, and git hooks.",
|
|
3
|
+
|
|
4
|
+
"apiKeys": [
|
|
5
|
+
{ "name": "AWS Access Key", "pattern": "AKIA[0-9A-Z]{16}", "severity": "critical" },
|
|
6
|
+
{ "name": "OpenAI API Key", "pattern": "sk-[a-zA-Z0-9]{48}", "severity": "critical" },
|
|
7
|
+
{ "name": "Anthropic API Key", "pattern": "sk-ant-[a-zA-Z0-9-]{90,}", "severity": "critical" },
|
|
8
|
+
{ "name": "GitHub Token (PAT)", "pattern": "ghp_[a-zA-Z0-9]{36}", "severity": "critical" },
|
|
9
|
+
{ "name": "GitHub OAuth Token", "pattern": "gho_[a-zA-Z0-9]{36}", "severity": "critical" },
|
|
10
|
+
{ "name": "GitLab Token", "pattern": "glpat-[a-zA-Z0-9-]{20}", "severity": "critical" },
|
|
11
|
+
{ "name": "Slack Bot Token", "pattern": "xoxb-[0-9]{10,}-[a-zA-Z0-9]{24}", "severity": "critical" },
|
|
12
|
+
{ "name": "Slack User Token", "pattern": "xoxp-[0-9]{10,}-[a-zA-Z0-9]{24}", "severity": "critical" },
|
|
13
|
+
{ "name": "SendGrid API Key", "pattern": "SG\\.[a-zA-Z0-9_-]{22}\\.[a-zA-Z0-9_-]{43}", "severity": "critical" },
|
|
14
|
+
{ "name": "Stripe Secret Key", "pattern": "sk_live_[a-zA-Z0-9]{24,}", "severity": "critical" },
|
|
15
|
+
{ "name": "Stripe Restricted Key", "pattern": "rk_live_[a-zA-Z0-9]{24,}", "severity": "critical" },
|
|
16
|
+
{ "name": "Square Access Token", "pattern": "sq0atp-[a-zA-Z0-9_-]{22}", "severity": "critical" },
|
|
17
|
+
{ "name": "Google API Key", "pattern": "AIza[0-9A-Za-z_-]{35}", "severity": "critical" },
|
|
18
|
+
{ "name": "Twilio API Key", "pattern": "SK[a-f0-9]{32}", "severity": "critical" },
|
|
19
|
+
{ "name": "Mailgun API Key", "pattern": "key-[a-zA-Z0-9]{32}", "severity": "critical" }
|
|
20
|
+
],
|
|
21
|
+
|
|
22
|
+
"credentials": [
|
|
23
|
+
{ "name": "Hardcoded password", "pattern": "password\\s*[:=]\\s*['\"][^'\"]{4,}['\"]", "severity": "critical" },
|
|
24
|
+
{ "name": "Hardcoded secret", "pattern": "secret\\s*[:=]\\s*['\"][^'\"]{4,}['\"]", "severity": "critical" },
|
|
25
|
+
{ "name": "Hardcoded API key", "pattern": "api[_-]?key\\s*[:=]\\s*['\"][^'\"]{4,}['\"]", "severity": "critical" },
|
|
26
|
+
{ "name": "Hardcoded token", "pattern": "auth[_-]?token\\s*[:=]\\s*['\"][^'\"]{4,}['\"]", "severity": "critical" },
|
|
27
|
+
{ "name": "OAuth client secret", "pattern": "client[_-]?secret\\s*[:=]\\s*['\"][^'\"]{4,}['\"]", "severity": "critical" }
|
|
28
|
+
],
|
|
29
|
+
|
|
30
|
+
"databaseUrls": [
|
|
31
|
+
{ "name": "MongoDB connection string", "pattern": "mongodb(\\+srv)?://[^/\\s]{8,}", "severity": "critical" },
|
|
32
|
+
{ "name": "PostgreSQL connection string", "pattern": "postgres(ql)?://[^/\\s]{8,}", "severity": "critical" },
|
|
33
|
+
{ "name": "MySQL connection string", "pattern": "mysql://[^/\\s]{8,}", "severity": "critical" },
|
|
34
|
+
{ "name": "Redis connection string", "pattern": "redis://[^/\\s]{8,}", "severity": "critical" },
|
|
35
|
+
{ "name": "RabbitMQ connection string", "pattern": "amqp://[^/\\s]{8,}", "severity": "critical" }
|
|
36
|
+
],
|
|
37
|
+
|
|
38
|
+
"privateKeys": [
|
|
39
|
+
{ "name": "RSA/EC/DSA Private Key", "pattern": "-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----", "severity": "critical" },
|
|
40
|
+
{ "name": "PGP Private Key", "pattern": "-----BEGIN PGP PRIVATE KEY BLOCK-----", "severity": "critical" }
|
|
41
|
+
],
|
|
42
|
+
|
|
43
|
+
"dangerousFiles": [
|
|
44
|
+
".env", ".env.local", ".env.production", ".env.staging", ".env.development",
|
|
45
|
+
"*.pem", "*.key", "*.p12", "*.pfx",
|
|
46
|
+
"credentials.json", "secrets.json", "service-account.json",
|
|
47
|
+
"id_rsa", "id_ed25519", "id_ecdsa",
|
|
48
|
+
".npmrc", ".netrc", ".htpasswd"
|
|
49
|
+
],
|
|
50
|
+
|
|
51
|
+
"falsePositives": [
|
|
52
|
+
"process.env.",
|
|
53
|
+
"os.environ",
|
|
54
|
+
"ENV[",
|
|
55
|
+
"<PLACEHOLDER>",
|
|
56
|
+
"YOUR_KEY_HERE",
|
|
57
|
+
"xxx",
|
|
58
|
+
"changeme",
|
|
59
|
+
".env.example",
|
|
60
|
+
".env.template"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ship-review
|
|
3
|
+
description: "AI code review. Analyzes code changes for logic errors, performance issues, database problems, security flaws, API contract violations, and more. Works on PRs, uncommitted changes, or full codebase."
|
|
4
|
+
argument-hint: "[--pr] [--full] [--focus CATEGORY] [--ci]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ship-review — AI Code Review
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
ship review # review uncommitted changes
|
|
13
|
+
ship review --pr # review current PR diff against main
|
|
14
|
+
ship review --full # review entire codebase
|
|
15
|
+
ship review --focus security # focus on one category
|
|
16
|
+
ship review --focus perf # focus on performance
|
|
17
|
+
ship review --ci # CI mode (structured output, exit code)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Modes
|
|
21
|
+
|
|
22
|
+
| Flag | Scope | Use when |
|
|
23
|
+
|------|-------|----------|
|
|
24
|
+
| (none) | Uncommitted changes | Before committing |
|
|
25
|
+
| `--pr` | PR diff (main..HEAD) | Before merging |
|
|
26
|
+
| `--full` | Entire codebase | Periodic audit |
|
|
27
|
+
| `--focus X` | Single category | Deep dive |
|
|
28
|
+
| `--ci` | Same as --pr, structured output | GitHub Actions |
|
|
29
|
+
|
|
30
|
+
## Workflow
|
|
31
|
+
|
|
32
|
+
### Step 1: Gather Changes
|
|
33
|
+
|
|
34
|
+
Based on mode, collect the code to review:
|
|
35
|
+
|
|
36
|
+
**Default (uncommitted):**
|
|
37
|
+
```bash
|
|
38
|
+
git diff --name-only
|
|
39
|
+
git diff
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**PR mode:**
|
|
43
|
+
```bash
|
|
44
|
+
git log main..HEAD --oneline
|
|
45
|
+
git diff main..HEAD --name-only
|
|
46
|
+
git diff main..HEAD
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Full mode:**
|
|
50
|
+
```bash
|
|
51
|
+
# Read all source files (exclude node_modules, .git, dist, build)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Step 2: Analyze
|
|
55
|
+
|
|
56
|
+
Read each changed file. For every file, check all categories from `references/review-categories.md`.
|
|
57
|
+
|
|
58
|
+
Use the `reviewer` agent for large diffs to keep main context clean.
|
|
59
|
+
|
|
60
|
+
### Step 3: Classify Findings
|
|
61
|
+
|
|
62
|
+
Assign severity per `references/severity-levels.md`.
|
|
63
|
+
|
|
64
|
+
### Step 4: Report
|
|
65
|
+
|
|
66
|
+
Output per `references/output-format.md`.
|
|
67
|
+
|
|
68
|
+
## Quick Reference
|
|
69
|
+
|
|
70
|
+
| Reference | Content |
|
|
71
|
+
|-----------|---------|
|
|
72
|
+
| `references/review-categories.md` | All review categories and what to check |
|
|
73
|
+
| `references/severity-levels.md` | How to classify findings |
|
|
74
|
+
| `references/output-format.md` | Report structure |
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Output Format
|
|
2
|
+
|
|
3
|
+
## Standard Report
|
|
4
|
+
|
|
5
|
+
```markdown
|
|
6
|
+
## Ship Review
|
|
7
|
+
|
|
8
|
+
### Critical
|
|
9
|
+
- [category] file/path.ts:LINE — Description of the issue
|
|
10
|
+
Fix: How to fix it
|
|
11
|
+
|
|
12
|
+
### Warning
|
|
13
|
+
- [category] file/path.ts:LINE — Description of the issue
|
|
14
|
+
Fix: How to fix it
|
|
15
|
+
|
|
16
|
+
### Suggestion
|
|
17
|
+
- [category] file/path.ts:LINE — Description of the issue
|
|
18
|
+
Fix: How to fix it
|
|
19
|
+
|
|
20
|
+
### Summary
|
|
21
|
+
Files reviewed: N
|
|
22
|
+
Critical: N | Warning: N | Suggestion: N
|
|
23
|
+
Verdict: PASS or FAIL
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Rules
|
|
27
|
+
|
|
28
|
+
- Group findings by severity (Critical first, then Warning, then Suggestion)
|
|
29
|
+
- Within each severity, order by impact (most impactful first)
|
|
30
|
+
- Include file path and line number for every finding
|
|
31
|
+
- Include category tag in brackets: [logic], [security], [performance], [database], [api], [error], [types], [payments], [webhooks], [integrations], [naming]
|
|
32
|
+
- Include a one-line fix suggestion for every finding
|
|
33
|
+
- If no findings at a severity level, omit that section
|
|
34
|
+
- Verdict is FAIL if any critical findings exist, PASS otherwise
|
|
35
|
+
- Keep descriptions concise (one line per finding, fix on next line)
|
|
36
|
+
- If same pattern appears in multiple files, group: "[performance] N+1 query pattern in 4 files: list..."
|
|
37
|
+
|
|
38
|
+
## CI Mode
|
|
39
|
+
|
|
40
|
+
Same format but:
|
|
41
|
+
- No conversational text before or after the report
|
|
42
|
+
- Just the markdown report
|
|
43
|
+
- Suitable for posting as a PR comment via `gh pr comment`
|
|
44
|
+
|
|
45
|
+
## Focus Mode
|
|
46
|
+
|
|
47
|
+
When `--focus CATEGORY` is used:
|
|
48
|
+
- Only report findings in that category
|
|
49
|
+
- Still use same format and severity levels
|
|
50
|
+
- Add a note at top: "Focused review: [category] only"
|
|
51
|
+
|
|
52
|
+
## No Issues Found
|
|
53
|
+
|
|
54
|
+
```markdown
|
|
55
|
+
## Ship Review
|
|
56
|
+
|
|
57
|
+
No issues found.
|
|
58
|
+
|
|
59
|
+
Files reviewed: N
|
|
60
|
+
Critical: 0 | Warning: 0 | Suggestion: 0
|
|
61
|
+
Verdict: PASS
|
|
62
|
+
```
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Review Categories
|
|
2
|
+
|
|
3
|
+
## Logic
|
|
4
|
+
|
|
5
|
+
Check for:
|
|
6
|
+
- Off-by-one errors in loops and array access
|
|
7
|
+
- Null/undefined paths not handled
|
|
8
|
+
- Race conditions in async code (parallel mutations, shared state)
|
|
9
|
+
- Infinite loops or unbounded recursion
|
|
10
|
+
- Wrong comparison operators (== vs ===, > vs >=)
|
|
11
|
+
- Inverted boolean logic (! in wrong place)
|
|
12
|
+
- Dead code paths that can never execute
|
|
13
|
+
- Missing return statements in branching logic
|
|
14
|
+
- Incorrect type coercion
|
|
15
|
+
- Switch/case without break or default
|
|
16
|
+
|
|
17
|
+
## Performance
|
|
18
|
+
|
|
19
|
+
Check for:
|
|
20
|
+
- N+1 database queries (loop with individual queries)
|
|
21
|
+
- Nested loops creating O(n^2) or worse complexity
|
|
22
|
+
- Unnecessary re-renders in React/frontend frameworks
|
|
23
|
+
- Memory leaks (event listeners not cleaned, intervals not cleared)
|
|
24
|
+
- Blocking calls in async contexts (sync file I/O, CPU-heavy in event loop)
|
|
25
|
+
- Missing pagination on large dataset queries
|
|
26
|
+
- Large payloads without streaming or compression
|
|
27
|
+
- Redundant computations that should be memoized or cached
|
|
28
|
+
- Missing cache headers on API responses
|
|
29
|
+
- No caching strategy for repeated expensive operations
|
|
30
|
+
- Stale cache without invalidation
|
|
31
|
+
- Loading entire collections when filtering would suffice
|
|
32
|
+
- Missing debounce/throttle on frequent events
|
|
33
|
+
- Unnecessary deep cloning of large objects
|
|
34
|
+
|
|
35
|
+
## Database
|
|
36
|
+
|
|
37
|
+
Check for:
|
|
38
|
+
- Missing indexes on columns used in WHERE, JOIN, ORDER BY
|
|
39
|
+
- SELECT * instead of specific columns
|
|
40
|
+
- No LIMIT on queries that could return large result sets
|
|
41
|
+
- Missing transactions on multi-step operations
|
|
42
|
+
- Unsafe migrations (dropping columns with data, renaming without backfill)
|
|
43
|
+
- No rollback/down migration defined
|
|
44
|
+
- Raw SQL with string concatenation (SQL injection risk)
|
|
45
|
+
- Missing connection pooling configuration
|
|
46
|
+
- No timeout on database queries
|
|
47
|
+
- Deadlock potential (acquiring locks in inconsistent order)
|
|
48
|
+
- Missing unique constraints where data should be unique
|
|
49
|
+
- No foreign key constraints on relationships
|
|
50
|
+
- Schema changes without data migration plan
|
|
51
|
+
- Missing created_at/updated_at timestamps
|
|
52
|
+
- No soft delete strategy when data retention matters
|
|
53
|
+
|
|
54
|
+
## Security
|
|
55
|
+
|
|
56
|
+
Check for:
|
|
57
|
+
- SQL injection (string interpolation in queries)
|
|
58
|
+
- XSS (unescaped user input in HTML/templates)
|
|
59
|
+
- Command injection (user input in shell commands)
|
|
60
|
+
- Hardcoded secrets, API keys, passwords
|
|
61
|
+
- Missing authentication on endpoints
|
|
62
|
+
- Missing authorization checks (user can access others' data)
|
|
63
|
+
- CSRF vulnerability (no token on state-changing requests)
|
|
64
|
+
- Insecure direct object references (sequential IDs in URLs)
|
|
65
|
+
- Path traversal (user input in file paths)
|
|
66
|
+
- Missing input validation and sanitization
|
|
67
|
+
- Passwords stored in plain text
|
|
68
|
+
- Sensitive data in logs
|
|
69
|
+
- Missing rate limiting on authentication endpoints
|
|
70
|
+
- JWT without expiration
|
|
71
|
+
- Insecure cookie settings (missing httpOnly, secure, sameSite)
|
|
72
|
+
|
|
73
|
+
## API Contracts
|
|
74
|
+
|
|
75
|
+
Check for:
|
|
76
|
+
- Inconsistent response format across endpoints
|
|
77
|
+
- Breaking changes to existing API (removed/renamed fields)
|
|
78
|
+
- Missing input validation on request body/params
|
|
79
|
+
- No error response standardization
|
|
80
|
+
- Missing HTTP status codes (always 200, even on error)
|
|
81
|
+
- Undocumented endpoints or parameters
|
|
82
|
+
- Missing Content-Type headers
|
|
83
|
+
- No request size limits
|
|
84
|
+
- Exposing internal errors/stack traces to clients
|
|
85
|
+
- Missing versioning strategy on breaking changes
|
|
86
|
+
- Inconsistent naming (camelCase vs snake_case in responses)
|
|
87
|
+
|
|
88
|
+
## Error Handling
|
|
89
|
+
|
|
90
|
+
Check for:
|
|
91
|
+
- Empty catch blocks (swallowed errors)
|
|
92
|
+
- Catch-all without specific error handling
|
|
93
|
+
- Unhandled promise rejections
|
|
94
|
+
- Missing error boundaries in UI frameworks
|
|
95
|
+
- Silent failures with no logging or user feedback
|
|
96
|
+
- Rethrowing errors without context
|
|
97
|
+
- Missing try/catch around external service calls
|
|
98
|
+
- No fallback for failed network requests
|
|
99
|
+
- Missing timeout handling on HTTP calls
|
|
100
|
+
- Error messages exposing implementation details
|
|
101
|
+
|
|
102
|
+
## Types
|
|
103
|
+
|
|
104
|
+
Check for:
|
|
105
|
+
- Type mismatches (string where number expected)
|
|
106
|
+
- Unsafe type casting (as any, type assertions)
|
|
107
|
+
- Missing null/undefined checks before property access
|
|
108
|
+
- Implicit any in TypeScript
|
|
109
|
+
- Wrong generic types
|
|
110
|
+
- Missing discriminated union checks
|
|
111
|
+
- Optional chaining hiding real bugs (?. masking null that shouldn't be null)
|
|
112
|
+
|
|
113
|
+
## Payments and Financial Operations
|
|
114
|
+
|
|
115
|
+
Check for:
|
|
116
|
+
- Missing idempotency key on payment/charge operations (double charge risk)
|
|
117
|
+
- Race condition on balance operations (concurrent debits can overdraw)
|
|
118
|
+
- No transaction wrapping on money operations (partial updates corrupt state)
|
|
119
|
+
- Trusting client-sent prices or amounts (price manipulation attack)
|
|
120
|
+
- Negative amounts not blocked (reverse charge exploit)
|
|
121
|
+
- Currency rounding errors (use integer cents, not floating point dollars)
|
|
122
|
+
- Missing reconciliation between payment provider and local DB
|
|
123
|
+
- No audit trail on financial operations (who charged what, when)
|
|
124
|
+
- Missing refund limits or cooldown period
|
|
125
|
+
- Balance check and debit not atomic (check-then-act race condition)
|
|
126
|
+
- No queue/lock for sequential financial operations on same account
|
|
127
|
+
- Missing retry handling with idempotency for failed payment calls
|
|
128
|
+
|
|
129
|
+
## Webhooks
|
|
130
|
+
|
|
131
|
+
Check for:
|
|
132
|
+
- No signature validation on incoming webhooks (Stripe, PayPal, etc.)
|
|
133
|
+
- Webhook secret hardcoded instead of environment variable
|
|
134
|
+
- No replay protection (same event processed multiple times)
|
|
135
|
+
- No idempotency on webhook handlers (duplicate events cause duplicate actions)
|
|
136
|
+
- Missing event type validation (processing unknown event types)
|
|
137
|
+
- No timeout on webhook processing (blocking the webhook provider)
|
|
138
|
+
- Webhook endpoint exposed without IP allowlisting or signature check
|
|
139
|
+
- Missing error handling that could lose webhook events
|
|
140
|
+
- No dead letter queue for failed webhook processing
|
|
141
|
+
- Returning 200 before processing completes (losing events on crash)
|
|
142
|
+
|
|
143
|
+
## Integrations (Third-Party APIs)
|
|
144
|
+
|
|
145
|
+
Check for:
|
|
146
|
+
- No timeout on external HTTP calls (hangs indefinitely)
|
|
147
|
+
- No circuit breaker (one failing service cascades to entire app)
|
|
148
|
+
- No retry with exponential backoff on transient failures
|
|
149
|
+
- Trusting external API response data without validation
|
|
150
|
+
- Missing error handling when integration is down
|
|
151
|
+
- No fallback or graceful degradation when dependency fails
|
|
152
|
+
- Sensitive data sent to third parties unnecessarily
|
|
153
|
+
- API keys for integrations hardcoded (use env vars)
|
|
154
|
+
- No request/response logging for debugging integration issues
|
|
155
|
+
- Missing rate limit handling on outbound API calls (429 responses)
|
|
156
|
+
- No health check for critical integration dependencies
|
|
157
|
+
|
|
158
|
+
## Naming and Readability
|
|
159
|
+
|
|
160
|
+
Check for:
|
|
161
|
+
- Single-letter variables outside loop counters
|
|
162
|
+
- Misleading function/variable names
|
|
163
|
+
- Inconsistent naming conventions within the file
|
|
164
|
+
- Functions doing more than one thing (god functions)
|
|
165
|
+
- Deep nesting (>3 levels)
|
|
166
|
+
- Files over 300 lines
|
|
167
|
+
- Magic numbers without named constants
|
|
168
|
+
- Boolean parameters without named arguments
|
|
169
|
+
- Commented-out code blocks
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Severity Levels
|
|
2
|
+
|
|
3
|
+
## Critical
|
|
4
|
+
|
|
5
|
+
Blocks merge in CI. Must fix before shipping.
|
|
6
|
+
|
|
7
|
+
Assign critical when:
|
|
8
|
+
- Security vulnerability exploitable in production
|
|
9
|
+
- Data loss or corruption possible
|
|
10
|
+
- Logic error that produces wrong results
|
|
11
|
+
- Breaking change to public API without migration
|
|
12
|
+
- Authentication/authorization bypass
|
|
13
|
+
- Race condition that causes data inconsistency
|
|
14
|
+
- Migration that destroys existing data
|
|
15
|
+
|
|
16
|
+
## Warning
|
|
17
|
+
|
|
18
|
+
Should fix. Flagged but doesn't block merge.
|
|
19
|
+
|
|
20
|
+
Assign warning when:
|
|
21
|
+
- Performance issue that degrades user experience
|
|
22
|
+
- Missing error handling that could cause silent failures
|
|
23
|
+
- Database query without index on large table
|
|
24
|
+
- Missing test coverage on critical path
|
|
25
|
+
- N+1 query pattern
|
|
26
|
+
- Missing input validation (non-security context)
|
|
27
|
+
- Cache strategy missing on hot path
|
|
28
|
+
- Inconsistent API response format
|
|
29
|
+
|
|
30
|
+
## Suggestion
|
|
31
|
+
|
|
32
|
+
Nice to have. Informational.
|
|
33
|
+
|
|
34
|
+
Assign suggestion when:
|
|
35
|
+
- Naming could be clearer
|
|
36
|
+
- Code could be simplified
|
|
37
|
+
- Minor style inconsistency
|
|
38
|
+
- Opportunity to extract reusable function
|
|
39
|
+
- Comment would help future readers
|
|
40
|
+
- Test could cover additional edge case
|
|
41
|
+
|
|
42
|
+
## Rules
|
|
43
|
+
|
|
44
|
+
- When in doubt between two levels, pick the higher one
|
|
45
|
+
- Never mark a security issue below Warning
|
|
46
|
+
- Never mark data loss risk below Critical
|
|
47
|
+
- If a finding is in dead/unreachable code, downgrade by one level
|
|
48
|
+
- If a finding is in test code only, downgrade by one level
|
|
49
|
+
- Group related findings (don't report same pattern 10 times)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ship-secure
|
|
3
|
+
description: "AI security scanner. Scans entire codebase for vulnerabilities, dependency CVEs, hardcoded secrets, exposed endpoints, webhook/payment security, and infrastructure misconfigurations."
|
|
4
|
+
argument-hint: "[--deps] [--vulns] [--secrets] [--ci]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ship-secure — AI Security Scanner
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
ship secure # full security scan
|
|
13
|
+
ship secure --deps # dependency vulnerabilities only
|
|
14
|
+
ship secure --vulns # vulnerability analysis only (OWASP, endpoints, webhooks, payments)
|
|
15
|
+
ship secure --secrets # secret detection only
|
|
16
|
+
ship secure --ci # CI mode (structured output, exit code)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Difference from ship-review
|
|
20
|
+
|
|
21
|
+
- **ship-review** checks your code CHANGES (PR diff) for security issues
|
|
22
|
+
- **ship-secure** scans the ENTIRE CODEBASE regardless of what changed
|
|
23
|
+
|
|
24
|
+
Run `ship-review` on every PR. Run `ship-secure` weekly or before releases.
|
|
25
|
+
|
|
26
|
+
## Workflow
|
|
27
|
+
|
|
28
|
+
### Step 1: Dependency Audit
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm audit 2>/dev/null || true
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Also read `package.json` / `package-lock.json` / `requirements.txt` / `go.mod` and check for known vulnerable versions.
|
|
35
|
+
|
|
36
|
+
Reference: `references/dependency-audit.md`
|
|
37
|
+
|
|
38
|
+
### Step 2: Secret Detection
|
|
39
|
+
|
|
40
|
+
Scan all source files for hardcoded secrets.
|
|
41
|
+
|
|
42
|
+
Reference: `references/secret-patterns.md`
|
|
43
|
+
|
|
44
|
+
### Step 3: Vulnerability Analysis
|
|
45
|
+
|
|
46
|
+
Read source code and check for OWASP categories, exposed endpoints, webhook/payment security, and infrastructure misconfigurations.
|
|
47
|
+
|
|
48
|
+
Reference: `references/owasp-checks.md`
|
|
49
|
+
|
|
50
|
+
### Step 4: Report
|
|
51
|
+
|
|
52
|
+
Output structured report with severity levels.
|
|
53
|
+
|
|
54
|
+
## Quick Reference
|
|
55
|
+
|
|
56
|
+
| Reference | Content |
|
|
57
|
+
|-----------|---------|
|
|
58
|
+
| `references/owasp-checks.md` | Vulnerability checks with code patterns |
|
|
59
|
+
| `references/dependency-audit.md` | Dependency vulnerability detection |
|
|
60
|
+
| `references/secret-patterns.md` | Secret and credential detection patterns |
|