ship-safe 3.0.0 → 3.2.0
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/README.md +626 -459
- package/cli/bin/ship-safe.js +200 -139
- package/cli/commands/agent.js +606 -0
- package/cli/commands/deps.js +447 -0
- package/cli/commands/fix.js +3 -3
- package/cli/commands/init.js +86 -3
- package/cli/commands/mcp.js +2 -2
- package/cli/commands/remediate.js +646 -0
- package/cli/commands/rotate.js +571 -0
- package/cli/commands/scan.js +64 -23
- package/cli/commands/score.js +446 -0
- package/cli/index.js +4 -1
- package/cli/utils/entropy.js +6 -0
- package/cli/utils/output.js +42 -2
- package/cli/utils/patterns.js +393 -1
- package/package.json +64 -63
package/README.md
CHANGED
|
@@ -1,459 +1,626 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src=".github/assets/logo%20ship%20safe.png" alt="Ship Safe Logo" width="180" />
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
<
|
|
10
|
-
<a href="https://
|
|
11
|
-
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a>
|
|
12
|
-
</p>
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
You're shipping fast. You're using AI to write code. You're one `git push` away from exposing your database credentials to the world.
|
|
17
|
-
|
|
18
|
-
**Ship Safe** is a security toolkit for indie hackers and vibe coders who want to secure their MVP in 5 minutes, not 5 days.
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Quick Start
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
#
|
|
26
|
-
npx ship-safe
|
|
27
|
-
|
|
28
|
-
#
|
|
29
|
-
npx ship-safe
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
npx ship-safe
|
|
33
|
-
|
|
34
|
-
#
|
|
35
|
-
npx ship-safe
|
|
36
|
-
|
|
37
|
-
#
|
|
38
|
-
npx ship-safe
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
**
|
|
165
|
-
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
|
261
|
-
|
|
262
|
-
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
3.
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/assets/logo%20ship%20safe.png" alt="Ship Safe Logo" width="180" />
|
|
3
|
+
</p>
|
|
4
|
+
<p align="center"><strong>Don't let vibe coding leak your API keys.</strong></p>
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="https://www.npmjs.com/package/ship-safe"><img src="https://badge.fury.io/js/ship-safe.svg" alt="npm version" /></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/ship-safe"><img src="https://img.shields.io/npm/dm/ship-safe.svg" alt="npm downloads" /></a>
|
|
9
|
+
<a href="https://github.com/asamassekou10/ship-safe/actions/workflows/ci.yml"><img src="https://github.com/asamassekou10/ship-safe/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
10
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/node/v/ship-safe" alt="Node.js version" /></a>
|
|
11
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
You're shipping fast. You're using AI to write code. You're one `git push` away from exposing your database credentials to the world.
|
|
17
|
+
|
|
18
|
+
**Ship Safe** is a security toolkit for indie hackers and vibe coders who want to secure their MVP in 5 minutes, not 5 days.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# AI-powered audit: scan, classify with Claude, auto-fix confirmed secrets
|
|
26
|
+
npx ship-safe agent .
|
|
27
|
+
|
|
28
|
+
# Scan for secrets AND code vulnerabilities (SQL injection, XSS, etc.)
|
|
29
|
+
npx ship-safe scan .
|
|
30
|
+
|
|
31
|
+
# Security health score (0-100, A–F grade)
|
|
32
|
+
npx ship-safe score .
|
|
33
|
+
|
|
34
|
+
# Audit dependencies for known CVEs
|
|
35
|
+
npx ship-safe deps .
|
|
36
|
+
|
|
37
|
+
# Auto-fix hardcoded secrets: rewrite code + write .env
|
|
38
|
+
npx ship-safe remediate .
|
|
39
|
+
|
|
40
|
+
# Revoke exposed keys — opens provider dashboards with step-by-step guide
|
|
41
|
+
npx ship-safe rotate .
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Or if you prefer the manual toolkit:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx ship-safe fix # Generate .env.example from secrets
|
|
48
|
+
npx ship-safe guard # Block git push if secrets found
|
|
49
|
+
npx ship-safe checklist # Run launch-day security checklist
|
|
50
|
+
npx ship-safe init # Add security configs to your project
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
### Let AI Do It For You
|
|
56
|
+
|
|
57
|
+
Copy this prompt to your AI coding assistant:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Run "npx ship-safe scan ." on my project and fix any secrets you find.
|
|
61
|
+
Then run "npx ship-safe init" to add security configs.
|
|
62
|
+
Explain what you're doing as you go.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
[More AI prompts for specific frameworks](./AI_SECURITY_PROMPT.md)
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Why This Exists
|
|
70
|
+
|
|
71
|
+
Vibe coding is powerful. You can build a SaaS in a weekend. But speed creates blind spots:
|
|
72
|
+
|
|
73
|
+
- AI-generated code often hardcodes secrets
|
|
74
|
+
- Default configs ship with debug mode enabled
|
|
75
|
+
- "I'll fix it later" becomes "I got hacked"
|
|
76
|
+
|
|
77
|
+
This repo is your co-pilot for security. Copy, paste, ship safely.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## CLI Commands
|
|
82
|
+
|
|
83
|
+
### `npx ship-safe agent [path]`
|
|
84
|
+
|
|
85
|
+
AI-powered security audit. Scans for both secrets and code vulnerabilities, sends findings to Claude for classification, auto-fixes confirmed secrets, and provides specific fix suggestions for code issues.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Full AI audit (requires ANTHROPIC_API_KEY)
|
|
89
|
+
npx ship-safe agent .
|
|
90
|
+
|
|
91
|
+
# Preview classification without writing any files
|
|
92
|
+
npx ship-safe agent . --dry-run
|
|
93
|
+
|
|
94
|
+
# Use a specific Claude model
|
|
95
|
+
npx ship-safe agent . --model claude-opus-4-6
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Flow:**
|
|
99
|
+
1. Scan for secrets + code vulnerabilities (XSS, SQLi, command injection, etc.)
|
|
100
|
+
2. Send findings to Claude — classify each as `REAL` or `FALSE_POSITIVE`
|
|
101
|
+
3. For secrets: auto-remediate confirmed findings (rewrite code + write `.env`)
|
|
102
|
+
4. For code vulns: print Claude's verdict + specific 1-line fix suggestion
|
|
103
|
+
5. Re-scan to verify secrets are gone
|
|
104
|
+
|
|
105
|
+
No `ANTHROPIC_API_KEY`? Falls back to `remediate` for secrets automatically.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
### `npx ship-safe scan [path]`
|
|
110
|
+
|
|
111
|
+
Scans your codebase for leaked secrets **and** code vulnerabilities.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Scan current directory
|
|
115
|
+
npx ship-safe scan .
|
|
116
|
+
|
|
117
|
+
# Scan a specific folder
|
|
118
|
+
npx ship-safe scan ./src
|
|
119
|
+
|
|
120
|
+
# Get JSON output (for CI pipelines)
|
|
121
|
+
npx ship-safe scan . --json
|
|
122
|
+
|
|
123
|
+
# SARIF output for GitHub Code Scanning
|
|
124
|
+
npx ship-safe scan . --sarif
|
|
125
|
+
|
|
126
|
+
# Verbose mode (show files being scanned)
|
|
127
|
+
npx ship-safe scan . -v
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Exit codes:** Returns `1` if issues found (useful for CI), `0` if clean.
|
|
131
|
+
|
|
132
|
+
**Flags:**
|
|
133
|
+
- `--json` — structured JSON output for CI pipelines
|
|
134
|
+
- `--sarif` — SARIF format for GitHub Code Scanning
|
|
135
|
+
- `--include-tests` — also scan test/spec/fixture files (excluded by default)
|
|
136
|
+
- `-v` — verbose mode
|
|
137
|
+
|
|
138
|
+
**Suppress false positives:**
|
|
139
|
+
```bash
|
|
140
|
+
const apiKey = 'example-key'; // ship-safe-ignore
|
|
141
|
+
```
|
|
142
|
+
Or exclude paths with `.ship-safeignore` (gitignore syntax).
|
|
143
|
+
|
|
144
|
+
**Custom patterns** — create `.ship-safe.json` in your project root:
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"patterns": [
|
|
148
|
+
{
|
|
149
|
+
"name": "My Internal API Key",
|
|
150
|
+
"pattern": "MYAPP_[A-Z0-9]{32}",
|
|
151
|
+
"severity": "high",
|
|
152
|
+
"description": "Internal key for myapp services."
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Detects 50+ secret patterns:**
|
|
159
|
+
- **AI/ML:** OpenAI, Anthropic, Google AI, Cohere, Replicate, Hugging Face
|
|
160
|
+
- **Auth:** Clerk, Auth0, Supabase Auth
|
|
161
|
+
- **Cloud:** AWS, Google Cloud, Azure
|
|
162
|
+
- **Database:** Supabase, PlanetScale, Neon, MongoDB, PostgreSQL, MySQL
|
|
163
|
+
- **Payment:** Stripe, PayPal
|
|
164
|
+
- **Messaging:** Twilio, SendGrid, Resend
|
|
165
|
+
- **And more:** GitHub tokens, private keys, JWTs, generic secrets
|
|
166
|
+
|
|
167
|
+
**Detects 18 code vulnerability patterns (OWASP Top 10):**
|
|
168
|
+
- **Injection:** SQL injection (template literals), command injection, code injection (`eval`)
|
|
169
|
+
- **XSS:** `dangerouslySetInnerHTML`, `innerHTML` assignment, `document.write`
|
|
170
|
+
- **Crypto:** MD5 / SHA-1 for passwords, weak random number generation
|
|
171
|
+
- **TLS:** `NODE_TLS_REJECT_UNAUTHORIZED=0`, `rejectUnauthorized: false`, Python `verify=False`
|
|
172
|
+
- **Deserialization:** `pickle.loads`, `yaml.load` without `Loader`
|
|
173
|
+
- **Misconfiguration:** CORS wildcard (`*`), deprecated `new Buffer()`
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
### `npx ship-safe remediate [path]`
|
|
178
|
+
|
|
179
|
+
Auto-fix hardcoded secrets: rewrites source files to use `process.env` variables, writes a `.env` file with the actual values, and updates `.gitignore`.
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Auto-fix secrets
|
|
183
|
+
npx ship-safe remediate .
|
|
184
|
+
|
|
185
|
+
# Preview changes without writing any files
|
|
186
|
+
npx ship-safe remediate . --dry-run
|
|
187
|
+
|
|
188
|
+
# Apply all fixes without prompting (for CI)
|
|
189
|
+
npx ship-safe remediate . --yes
|
|
190
|
+
|
|
191
|
+
# Also run git add on modified files
|
|
192
|
+
npx ship-safe remediate . --stage
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
### `npx ship-safe rotate [path]`
|
|
198
|
+
|
|
199
|
+
Revoke and rotate exposed secrets. Detects which providers your secrets belong to and opens the right dashboard with step-by-step revocation instructions.
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Open dashboards for all detected secrets
|
|
203
|
+
npx ship-safe rotate .
|
|
204
|
+
|
|
205
|
+
# Rotate only a specific provider
|
|
206
|
+
npx ship-safe rotate . --provider github
|
|
207
|
+
npx ship-safe rotate . --provider stripe
|
|
208
|
+
npx ship-safe rotate . --provider openai
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Supports:** OpenAI, Anthropic, GitHub, Stripe, AWS, Google Cloud, Supabase, and more.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### `npx ship-safe deps [path]`
|
|
216
|
+
|
|
217
|
+
Audit your dependencies for known CVEs using the project's native package manager.
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Audit dependencies
|
|
221
|
+
npx ship-safe deps .
|
|
222
|
+
|
|
223
|
+
# Also run the package manager's auto-fix command
|
|
224
|
+
npx ship-safe deps . --fix
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Supported package managers:**
|
|
228
|
+
- `npm` → `npm audit`
|
|
229
|
+
- `yarn` → `yarn audit`
|
|
230
|
+
- `pnpm` → `pnpm audit`
|
|
231
|
+
- `pip` → `pip-audit` (install with `pip install pip-audit`)
|
|
232
|
+
- `bundler` → `bundle-audit` (install with `gem install bundler-audit`)
|
|
233
|
+
|
|
234
|
+
Auto-detected from your lock file. Gracefully skips if the tool isn't installed.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
### `npx ship-safe score [path]`
|
|
239
|
+
|
|
240
|
+
Compute a 0–100 security health score for your project. Combines secret detection, code vulnerability detection, and dependency CVEs into a single grade. No API key needed — instant and free.
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Score the project
|
|
244
|
+
npx ship-safe score .
|
|
245
|
+
|
|
246
|
+
# Skip dependency audit (faster)
|
|
247
|
+
npx ship-safe score . --no-deps
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Scoring (starts at 100):**
|
|
251
|
+
|
|
252
|
+
| Category | Critical | High | Medium | Cap |
|
|
253
|
+
|----------|----------|------|--------|-----|
|
|
254
|
+
| Secrets | −25 | −15 | −5 | −40 |
|
|
255
|
+
| Code Vulns | −20 | −10 | −3 | −30 |
|
|
256
|
+
| Dependencies | −20 | −10 | −5 | −30 |
|
|
257
|
+
|
|
258
|
+
**Grades:**
|
|
259
|
+
|
|
260
|
+
| Score | Grade | Verdict |
|
|
261
|
+
|-------|-------|---------|
|
|
262
|
+
| 90–100 | A | Ship it! |
|
|
263
|
+
| 75–89 | B | Minor issues to review |
|
|
264
|
+
| 60–74 | C | Fix before shipping |
|
|
265
|
+
| 40–59 | D | Significant security risks |
|
|
266
|
+
| 0–39 | F | Not safe to ship |
|
|
267
|
+
|
|
268
|
+
**Exit codes:** Returns `0` for A/B (≥ 75), `1` for C/D/F.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
### `npx ship-safe checklist`
|
|
273
|
+
|
|
274
|
+
Interactive 10-point security checklist for launch day.
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
# Interactive mode (prompts for each item)
|
|
278
|
+
npx ship-safe checklist
|
|
279
|
+
|
|
280
|
+
# Print checklist without prompts
|
|
281
|
+
npx ship-safe checklist --no-interactive
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Covers: exposed .git folders, debug mode, RLS policies, hardcoded keys, HTTPS, security headers, rate limiting, and more.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
### `npx ship-safe init`
|
|
289
|
+
|
|
290
|
+
Initialize security configs in your project.
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Add all security configs
|
|
294
|
+
npx ship-safe init
|
|
295
|
+
|
|
296
|
+
# Only add .gitignore patterns
|
|
297
|
+
npx ship-safe init --gitignore
|
|
298
|
+
|
|
299
|
+
# Only add security headers config
|
|
300
|
+
npx ship-safe init --headers
|
|
301
|
+
|
|
302
|
+
# Force overwrite existing files
|
|
303
|
+
npx ship-safe init -f
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**What it copies:**
|
|
307
|
+
- `.gitignore` - Patterns to prevent committing secrets
|
|
308
|
+
- `security-headers.config.js` - Drop-in Next.js security headers
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### `npx ship-safe fix`
|
|
313
|
+
|
|
314
|
+
Scan for secrets and auto-generate a `.env.example` file.
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# Scan and generate .env.example
|
|
318
|
+
npx ship-safe fix
|
|
319
|
+
|
|
320
|
+
# Preview what would be generated without writing it
|
|
321
|
+
npx ship-safe fix --dry-run
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
### `npx ship-safe guard`
|
|
327
|
+
|
|
328
|
+
Install a git hook that blocks pushes if secrets are found. Works with or without Husky.
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# Install pre-push hook (runs scan before every git push)
|
|
332
|
+
npx ship-safe guard
|
|
333
|
+
|
|
334
|
+
# Install pre-commit hook instead
|
|
335
|
+
npx ship-safe guard --pre-commit
|
|
336
|
+
|
|
337
|
+
# Remove installed hooks
|
|
338
|
+
npx ship-safe guard remove
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**Suppress false positives:**
|
|
342
|
+
- Add `# ship-safe-ignore` as a comment on a line to skip it
|
|
343
|
+
- Create `.ship-safeignore` (gitignore syntax) to exclude paths
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
### `npx ship-safe mcp`
|
|
348
|
+
|
|
349
|
+
Start ship-safe as an MCP server so AI editors can call it directly.
|
|
350
|
+
|
|
351
|
+
**Setup (Claude Desktop)** — add to `claude_desktop_config.json`:
|
|
352
|
+
```json
|
|
353
|
+
{
|
|
354
|
+
"mcpServers": {
|
|
355
|
+
"ship-safe": {
|
|
356
|
+
"command": "npx",
|
|
357
|
+
"args": ["ship-safe", "mcp"]
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Works with Claude Desktop, Cursor, Windsurf, Zed, and any MCP-compatible editor.
|
|
364
|
+
|
|
365
|
+
**Available tools:**
|
|
366
|
+
- `scan_secrets` — scan a directory for leaked secrets
|
|
367
|
+
- `get_checklist` — return the security checklist as structured data
|
|
368
|
+
- `analyze_file` — analyze a single file for issues
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## What's Inside
|
|
373
|
+
|
|
374
|
+
### [`/checklists`](./checklists)
|
|
375
|
+
**Manual security audits you can do in 5 minutes.**
|
|
376
|
+
- [Launch Day Checklist](./checklists/launch-day.md) - 10 things to check before you go live
|
|
377
|
+
|
|
378
|
+
### [`/configs`](./configs)
|
|
379
|
+
**Secure defaults for popular stacks. Drop-in ready.**
|
|
380
|
+
|
|
381
|
+
| Stack | Files |
|
|
382
|
+
|-------|-------|
|
|
383
|
+
| **Next.js** | [Security Headers](./configs/nextjs-security-headers.js) - CSP, X-Frame-Options, HSTS |
|
|
384
|
+
| **Supabase** | [RLS Templates](./configs/supabase/rls-templates.sql) \| [Security Checklist](./configs/supabase/security-checklist.md) \| [Secure Client](./configs/supabase/secure-client.ts) |
|
|
385
|
+
| **Firebase** | [Firestore Rules](./configs/firebase/firestore-rules.txt) \| [Storage Rules](./configs/firebase/storage-rules.txt) \| [Security Checklist](./configs/firebase/security-checklist.md) |
|
|
386
|
+
|
|
387
|
+
### [`/snippets`](./snippets)
|
|
388
|
+
**Copy-paste code blocks for common security patterns.**
|
|
389
|
+
|
|
390
|
+
| Category | Files |
|
|
391
|
+
|----------|-------|
|
|
392
|
+
| **Rate Limiting** | [Upstash Redis](./snippets/rate-limiting/upstash-ratelimit.ts) \| [Next.js Middleware](./snippets/rate-limiting/nextjs-middleware.ts) |
|
|
393
|
+
| **Authentication** | [JWT Security Checklist](./snippets/auth/jwt-checklist.md) |
|
|
394
|
+
| **API Security** | [CORS Config](./snippets/api-security/cors-config.ts) \| [Input Validation](./snippets/api-security/input-validation.ts) \| [API Checklist](./snippets/api-security/api-security-checklist.md) |
|
|
395
|
+
|
|
396
|
+
### [`/ai-defense`](./ai-defense)
|
|
397
|
+
**Protect your AI features from abuse and cost explosions.**
|
|
398
|
+
|
|
399
|
+
| File | Description |
|
|
400
|
+
|------|-------------|
|
|
401
|
+
| [LLM Security Checklist](./ai-defense/llm-security-checklist.md) | Based on OWASP LLM Top 10 - prompt injection, data protection, scope control |
|
|
402
|
+
| [Prompt Injection Patterns](./ai-defense/prompt-injection-patterns.js) | Regex patterns to detect 25+ injection attempts |
|
|
403
|
+
| [Cost Protection Guide](./ai-defense/cost-protection.md) | Prevent $50k surprise bills - rate limits, budget caps, circuit breakers |
|
|
404
|
+
| [System Prompt Armor](./ai-defense/system-prompt-armor.md) | Template for hardened system prompts |
|
|
405
|
+
|
|
406
|
+
### [`/scripts`](./scripts)
|
|
407
|
+
**Automated scanning tools. Run them in CI or locally.**
|
|
408
|
+
- [Secret Scanner](./scripts/scan_secrets.py) - Python version of the secret scanner
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## AI/LLM Security
|
|
413
|
+
|
|
414
|
+
Building with AI? Don't let it bankrupt you or get hijacked.
|
|
415
|
+
|
|
416
|
+
### Quick Setup
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
import { containsInjectionAttempt } from './ai-defense/prompt-injection-patterns';
|
|
420
|
+
|
|
421
|
+
async function handleChat(userInput: string) {
|
|
422
|
+
// 1. Check for injection attempts
|
|
423
|
+
const { detected } = containsInjectionAttempt(userInput);
|
|
424
|
+
if (detected) {
|
|
425
|
+
return "I can't process that request.";
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// 2. Rate limit per user
|
|
429
|
+
const { success } = await ratelimit.limit(userId);
|
|
430
|
+
if (!success) {
|
|
431
|
+
return "Too many requests. Please slow down.";
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// 3. Check budget before calling
|
|
435
|
+
await checkUserBudget(userId, estimatedCost);
|
|
436
|
+
|
|
437
|
+
// 4. Make the API call with token limits
|
|
438
|
+
const response = await openai.chat.completions.create({
|
|
439
|
+
model: 'gpt-4',
|
|
440
|
+
messages,
|
|
441
|
+
max_tokens: 500, // Hard cap
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
return response;
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Cost Protection Layers
|
|
449
|
+
|
|
450
|
+
1. **Token limits** - Cap input/output per request
|
|
451
|
+
2. **Rate limits** - Cap requests per user (10/min)
|
|
452
|
+
3. **Budget caps** - Daily ($1) and monthly ($10) per user
|
|
453
|
+
4. **Circuit breaker** - Disable AI when global budget hit
|
|
454
|
+
5. **Provider limits** - Set hard limits in OpenAI/Anthropic dashboard
|
|
455
|
+
|
|
456
|
+
[Full cost protection guide →](./ai-defense/cost-protection.md)
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Database Security
|
|
461
|
+
|
|
462
|
+
### Supabase RLS Templates
|
|
463
|
+
|
|
464
|
+
```sql
|
|
465
|
+
-- Users can only see their own data
|
|
466
|
+
CREATE POLICY "Users own their data" ON items
|
|
467
|
+
FOR ALL USING (auth.uid() = user_id);
|
|
468
|
+
|
|
469
|
+
-- Read-only public data
|
|
470
|
+
CREATE POLICY "Public read access" ON public_items
|
|
471
|
+
FOR SELECT USING (true);
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
[6 more RLS patterns →](./configs/supabase/rls-templates.sql)
|
|
475
|
+
|
|
476
|
+
### Firebase Security Rules
|
|
477
|
+
|
|
478
|
+
```javascript
|
|
479
|
+
// Users can only access their own documents
|
|
480
|
+
match /users/{userId} {
|
|
481
|
+
allow read, write: if request.auth != null
|
|
482
|
+
&& request.auth.uid == userId;
|
|
483
|
+
}
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
[Full Firestore rules template →](./configs/firebase/firestore-rules.txt)
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
## API Security
|
|
491
|
+
|
|
492
|
+
### CORS (Don't use `*` in production)
|
|
493
|
+
|
|
494
|
+
```typescript
|
|
495
|
+
const ALLOWED_ORIGINS = [
|
|
496
|
+
'https://yourapp.com',
|
|
497
|
+
'https://www.yourapp.com',
|
|
498
|
+
];
|
|
499
|
+
|
|
500
|
+
// Only allow specific origins
|
|
501
|
+
if (origin && ALLOWED_ORIGINS.includes(origin)) {
|
|
502
|
+
headers['Access-Control-Allow-Origin'] = origin;
|
|
503
|
+
}
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
[CORS configs for Next.js, Express, Fastify, Hono →](./snippets/api-security/cors-config.ts)
|
|
507
|
+
|
|
508
|
+
### Input Validation (Zod)
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
const createUserSchema = z.object({
|
|
512
|
+
email: z.string().email().max(255),
|
|
513
|
+
password: z.string().min(8).max(128),
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
const result = createUserSchema.safeParse(body);
|
|
517
|
+
if (!result.success) {
|
|
518
|
+
return Response.json({ error: result.error.issues }, { status: 400 });
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
[Full validation patterns →](./snippets/api-security/input-validation.ts)
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
## CI/CD Integration
|
|
527
|
+
|
|
528
|
+
Add to your GitHub Actions workflow:
|
|
529
|
+
|
|
530
|
+
```yaml
|
|
531
|
+
# .github/workflows/security.yml
|
|
532
|
+
name: Security Scan
|
|
533
|
+
|
|
534
|
+
on: [push, pull_request]
|
|
535
|
+
|
|
536
|
+
jobs:
|
|
537
|
+
security:
|
|
538
|
+
runs-on: ubuntu-latest
|
|
539
|
+
steps:
|
|
540
|
+
- uses: actions/checkout@v4
|
|
541
|
+
|
|
542
|
+
- name: Scan for secrets and code vulnerabilities
|
|
543
|
+
run: npx ship-safe scan . --json
|
|
544
|
+
|
|
545
|
+
- name: Audit dependencies for CVEs
|
|
546
|
+
run: npx ship-safe deps .
|
|
547
|
+
|
|
548
|
+
- name: Security health score (fail if C or below)
|
|
549
|
+
run: npx ship-safe score . --no-deps
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Each command exits with code `1` on findings, failing your build. Use `--sarif` with `scan` to send results to GitHub's Security tab:
|
|
553
|
+
|
|
554
|
+
```yaml
|
|
555
|
+
- name: Scan (SARIF for GitHub Security tab)
|
|
556
|
+
run: npx ship-safe scan . --sarif > results.sarif
|
|
557
|
+
|
|
558
|
+
- name: Upload to GitHub Security tab
|
|
559
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
560
|
+
with:
|
|
561
|
+
sarif_file: results.sarif
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
---
|
|
565
|
+
|
|
566
|
+
## The 5-Minute Security Checklist
|
|
567
|
+
|
|
568
|
+
1. ✅ Run `npx ship-safe agent .` — AI audit: finds + classifies + fixes secrets and code vulns
|
|
569
|
+
2. ✅ Run `npx ship-safe deps .` — audit your dependencies for known CVEs
|
|
570
|
+
3. ✅ Run `npx ship-safe score .` — check your overall security health score
|
|
571
|
+
4. ✅ Run `npx ship-safe init` — add security configs (.gitignore, security headers)
|
|
572
|
+
5. ✅ Run `npx ship-safe guard` — install git hook to block pushes if secrets found
|
|
573
|
+
6. ✅ Run `npx ship-safe checklist` — run the interactive launch-day security checklist
|
|
574
|
+
7. ✅ If using AI features, implement [cost protection](./ai-defense/cost-protection.md)
|
|
575
|
+
8. ✅ If using Supabase, check the [RLS checklist](./configs/supabase/security-checklist.md)
|
|
576
|
+
9. ✅ If using Firebase, check the [Firebase checklist](./configs/firebase/security-checklist.md)
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
## Philosophy
|
|
581
|
+
|
|
582
|
+
- **Low friction** - If it takes more than 5 minutes, people won't do it
|
|
583
|
+
- **Educational** - Every config has comments explaining *why*
|
|
584
|
+
- **Modular** - Take what you need, ignore the rest
|
|
585
|
+
- **Copy-paste friendly** - No complex setup, just grab and go
|
|
586
|
+
|
|
587
|
+
---
|
|
588
|
+
|
|
589
|
+
## Contributing
|
|
590
|
+
|
|
591
|
+
Found a security pattern that saved your app? Share it!
|
|
592
|
+
|
|
593
|
+
1. Fork the repo
|
|
594
|
+
2. Add your checklist, config, or script
|
|
595
|
+
3. Include educational comments explaining *why* it matters
|
|
596
|
+
4. Open a PR
|
|
597
|
+
|
|
598
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
## Security Standards Reference
|
|
603
|
+
|
|
604
|
+
This toolkit is based on:
|
|
605
|
+
- [OWASP Top 10 Web 2025](https://owasp.org/Top10/)
|
|
606
|
+
- [OWASP Top 10 Mobile 2024](https://owasp.org/www-project-mobile-top-10/)
|
|
607
|
+
- [OWASP LLM Top 10 2025](https://genai.owasp.org/llm-top-10/)
|
|
608
|
+
- [OWASP API Security Top 10 2023](https://owasp.org/API-Security/)
|
|
609
|
+
|
|
610
|
+
---
|
|
611
|
+
|
|
612
|
+
## License
|
|
613
|
+
|
|
614
|
+
MIT - Use it, share it, secure your stuff.
|
|
615
|
+
|
|
616
|
+
---
|
|
617
|
+
|
|
618
|
+
## Star History
|
|
619
|
+
|
|
620
|
+
[](https://star-history.com/#asamassekou10/ship-safe&Date)
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
624
|
+
**Remember: Security isn't about being paranoid. It's about being prepared.**
|
|
625
|
+
|
|
626
|
+
Ship fast. Ship safe.
|