bastion-scan 0.1.0 → 0.1.3

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.
Files changed (3) hide show
  1. package/README.md +9 -9
  2. package/dist/index.js +118 -13
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  <img alt="Build" src="https://img.shields.io/github/actions/workflow/status/absastreon/bastion/ci.yml?branch=main&style=flat-square" />
8
8
  <img alt="Tests" src="https://img.shields.io/badge/tests-783%20passing-brightgreen?style=flat-square" />
9
9
  <img alt="License" src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" />
10
- <img alt="npm" src="https://img.shields.io/npm/v/@bastion/cli?style=flat-square" />
10
+ <img alt="npm" src="https://img.shields.io/npm/v/bastion-scan?style=flat-square" />
11
11
  </p>
12
12
 
13
13
  ---
@@ -26,19 +26,19 @@ Every finding comes with a prompt you can paste into Claude, ChatGPT, or Copilot
26
26
 
27
27
  ```bash
28
28
  # Install globally
29
- npm install -g @bastion/cli
29
+ npm install -g bastion-scan
30
30
 
31
31
  # Scan your project
32
- npx bastion scan
32
+ npx bastion-scan scan
33
33
 
34
34
  # Scan a live URL (headers, SSL, security.txt)
35
- npx bastion scan --url https://yourapp.com
35
+ npx bastion-scan scan --url https://yourapp.com
36
36
 
37
37
  # JSON output for CI/CD
38
- npx bastion scan --format json
38
+ npx bastion-scan scan --format json
39
39
 
40
40
  # Generate security configs for your stack
41
- npx bastion scan --generate-configs
41
+ npx bastion-scan scan --generate-configs
42
42
  ```
43
43
 
44
44
  ---
@@ -48,7 +48,7 @@ npx bastion scan --generate-configs
48
48
  | Check | What it does |
49
49
  |-------|-------------|
50
50
  | `.gitignore` coverage | Makes sure `.env`, `node_modules`, and keys are excluded |
51
- | Hardcoded secrets | Looks for API keys from OpenAI, Stripe, AWS, and others |
51
+ | Hardcoded secrets | API keys from OpenAI, Anthropic, GitHub, Stripe, AWS, Google, Slack, and more |
52
52
  | Dependency audit | Wraps `npm audit` and maps findings to severity levels |
53
53
  | `.env.example` | Checks that a template exists with safe placeholder values |
54
54
  | `security.txt` | Validates RFC 9116 Contact + Expires fields |
@@ -83,7 +83,7 @@ Bastion can output ready-to-paste configs for your stack:
83
83
  Interactive CLI that walks you through creating a valid RFC 9116 `security.txt`:
84
84
 
85
85
  ```bash
86
- npx bastion generate security-txt
86
+ npx bastion-scan generate security-txt
87
87
  ```
88
88
 
89
89
  ---
@@ -193,7 +193,7 @@ Floor is 0. Only `fail` results deduct. `warn`, `skip`, and `pass` don't affect
193
193
  ```
194
194
  bastion/
195
195
  ├── packages/
196
- │ ├── cli/ # npx bastion scan, 12 checks, 3 reporters
196
+ │ ├── cli/ # npx bastion-scan scan, 12 checks, 3 reporters
197
197
  │ ├── shared/ # Types, checklist data, OWASP data, tools
198
198
  │ └── web/ # Next.js 14 dashboard
199
199
  └── docs/playbooks/ # Stack-specific security guides
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { createRequire } from "module";
7
7
  import { Command, Option } from "commander";
8
8
  import chalk2 from "chalk";
9
9
  import ora from "ora";
10
- import { OUTPUT_FORMATS } from "@bastion/shared";
10
+ import { OUTPUT_FORMATS } from "bastion-shared";
11
11
 
12
12
  // src/scanner.ts
13
13
  import { readdir, readFile as readFile9, stat } from "fs/promises";
@@ -196,40 +196,145 @@ var SCANNABLE_EXTENSIONS = /* @__PURE__ */ new Set([
196
196
  ]);
197
197
  var IGNORED_DIRS = /* @__PURE__ */ new Set(["node_modules", "dist", "build", ".git", "tests", "__tests__", "test", "fixtures"]);
198
198
  var SECRET_PATTERNS = [
199
+ // ── OpenAI ──────────────────────────────────────────────────────────────
199
200
  {
200
- name: "OpenAI API key",
201
- regex: /sk-[A-Za-z0-9]{20,}/,
202
- description: "OpenAI API key detected"
201
+ name: "OpenAI API key (project)",
202
+ regex: /sk-proj-[a-zA-Z0-9_-]{20,}/,
203
+ description: "OpenAI project API key detected",
204
+ severity: "critical"
203
205
  },
206
+ {
207
+ name: "OpenAI API key (service account)",
208
+ regex: /sk-svcacct-[a-zA-Z0-9_-]{20,}/,
209
+ description: "OpenAI service account key detected",
210
+ severity: "critical"
211
+ },
212
+ {
213
+ name: "OpenAI API key (legacy)",
214
+ regex: /sk-[a-zA-Z0-9]{20,}/,
215
+ description: "OpenAI API key detected",
216
+ severity: "critical"
217
+ },
218
+ // ── Anthropic ───────────────────────────────────────────────────────────
219
+ {
220
+ name: "Anthropic API key",
221
+ regex: /sk-ant-api[0-9]{2}-[a-zA-Z0-9_-]{40,}/,
222
+ description: "Anthropic API key detected",
223
+ severity: "critical"
224
+ },
225
+ {
226
+ name: "Anthropic admin key",
227
+ regex: /sk-ant-admin[0-9]{2}-[a-zA-Z0-9_-]{40,}/,
228
+ description: "Anthropic admin API key detected",
229
+ severity: "critical"
230
+ },
231
+ // ── GitHub ──────────────────────────────────────────────────────────────
232
+ {
233
+ name: "GitHub PAT (classic)",
234
+ regex: /ghp_[a-zA-Z0-9]{36}/,
235
+ description: "GitHub personal access token (classic) detected",
236
+ severity: "critical"
237
+ },
238
+ {
239
+ name: "GitHub OAuth token",
240
+ regex: /gho_[a-zA-Z0-9]{36}/,
241
+ description: "GitHub OAuth access token detected",
242
+ severity: "critical"
243
+ },
244
+ {
245
+ name: "GitHub PAT (fine-grained)",
246
+ regex: /github_pat_[a-zA-Z0-9_]{82}/,
247
+ description: "GitHub fine-grained personal access token detected",
248
+ severity: "critical"
249
+ },
250
+ {
251
+ name: "GitHub app token",
252
+ regex: /ghs_[a-zA-Z0-9]{36}/,
253
+ description: "GitHub app installation token detected",
254
+ severity: "critical"
255
+ },
256
+ {
257
+ name: "GitHub refresh token",
258
+ regex: /ghr_[a-zA-Z0-9]{36}/,
259
+ description: "GitHub refresh token detected",
260
+ severity: "critical"
261
+ },
262
+ // ── Stripe ──────────────────────────────────────────────────────────────
204
263
  {
205
264
  name: "Stripe secret key",
206
- regex: /sk_live_[A-Za-z0-9]{20,}/,
207
- description: "Stripe secret key detected"
265
+ regex: /sk_live_[a-zA-Z0-9]{24,}/,
266
+ description: "Stripe secret key detected",
267
+ severity: "critical"
208
268
  },
209
269
  {
210
270
  name: "Stripe publishable key",
211
- regex: /pk_live_[A-Za-z0-9]{20,}/,
212
- description: "Stripe publishable live key detected"
271
+ regex: /pk_live_[a-zA-Z0-9]{20,}/,
272
+ description: "Stripe publishable live key detected",
273
+ severity: "critical"
274
+ },
275
+ {
276
+ name: "Stripe restricted key",
277
+ regex: /rk_live_[a-zA-Z0-9]{24,}/,
278
+ description: "Stripe restricted API key detected",
279
+ severity: "critical"
213
280
  },
281
+ {
282
+ name: "Stripe test key",
283
+ regex: /sk_test_[a-zA-Z0-9]{24,}/,
284
+ description: "Stripe test secret key detected",
285
+ severity: "high"
286
+ },
287
+ // ── AWS ─────────────────────────────────────────────────────────────────
214
288
  {
215
289
  name: "AWS access key",
216
290
  regex: /AKIA[0-9A-Z]{16}/,
217
- description: "AWS access key ID detected"
291
+ description: "AWS access key ID detected",
292
+ severity: "critical"
293
+ },
294
+ // ── Google ──────────────────────────────────────────────────────────────
295
+ {
296
+ name: "Google API key",
297
+ regex: /AIza[a-zA-Z0-9_-]{35}/,
298
+ description: "Google API key detected",
299
+ severity: "critical"
218
300
  },
301
+ // ── Slack ───────────────────────────────────────────────────────────────
302
+ {
303
+ name: "Slack bot token",
304
+ regex: /xoxb-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24,}/,
305
+ description: "Slack bot token detected",
306
+ severity: "critical"
307
+ },
308
+ {
309
+ name: "Slack user token",
310
+ regex: /xoxp-[0-9]{10,13}-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{32}/,
311
+ description: "Slack user token detected",
312
+ severity: "critical"
313
+ },
314
+ {
315
+ name: "Slack webhook URL",
316
+ regex: /https:\/\/hooks\.slack\.com\/services\/T[a-zA-Z0-9]{8,12}\/B[a-zA-Z0-9]{8,12}\/[a-zA-Z0-9]{24}/,
317
+ description: "Slack incoming webhook URL detected",
318
+ severity: "high"
319
+ },
320
+ // ── Generic ─────────────────────────────────────────────────────────────
219
321
  {
220
322
  name: "Generic API key assignment",
221
323
  regex: /(?:api[_-]?key|apikey|api[_-]?secret)\s*[:=]\s*['"][A-Za-z0-9_\-/.]{8,}['"]/i,
222
- description: "Hardcoded API key assignment detected"
324
+ description: "Hardcoded API key assignment detected",
325
+ severity: "critical"
223
326
  },
224
327
  {
225
328
  name: "Bearer token",
226
329
  regex: /['"]Bearer\s+[A-Za-z0-9_\-/.+]{20,}['"]/,
227
- description: "Hardcoded Bearer token detected"
330
+ description: "Hardcoded Bearer token detected",
331
+ severity: "critical"
228
332
  },
229
333
  {
230
334
  name: "Database connection string",
231
335
  regex: /(?:mongodb(?:\+srv)?|postgres(?:ql)?|mysql|redis):\/\/[^:]+:[^@\s]+@/i,
232
- description: "Database connection string with embedded password detected"
336
+ description: "Database connection string with embedded password detected",
337
+ severity: "critical"
233
338
  }
234
339
  ];
235
340
  var AI_PROMPT = "I found a hardcoded secret in my source code. Help me move it to an environment variable. Show me: (1) how to add it to .env, (2) how to read it with process.env or the equivalent for my framework, (3) how to add the key name to .env.example with a placeholder value, and (4) how to validate at startup that the variable is set.";
@@ -265,7 +370,7 @@ function scanContent(content, relativePath) {
265
370
  id: "secrets",
266
371
  name: `Hardcoded secret: ${pattern.name}`,
267
372
  status: "fail",
268
- severity: "critical",
373
+ severity: pattern.severity,
269
374
  category: "Secrets",
270
375
  location: `${relativePath}:${i + 1}`,
271
376
  description: pattern.description,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bastion-scan",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "Privacy-first security checker for web projects. 15 checks, zero data uploaded, actionable fixes.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,7 +37,7 @@
37
37
  "dev": "tsup --watch"
38
38
  },
39
39
  "dependencies": {
40
- "@bastion/shared": "*",
40
+ "bastion-shared": "^0.1.3",
41
41
  "chalk": "^5.6.2",
42
42
  "commander": "^14.0.3",
43
43
  "ora": "^9.3.0"