@node9/policy-engine 1.5.0 → 1.27.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/dist/index.js CHANGED
@@ -525,6 +525,42 @@ var DLP_PATTERNS = [
525
525
  regex: /\bAGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JNLH]{58}\b/,
526
526
  severity: "block",
527
527
  keywords: ["age-secret-key-"]
528
+ },
529
+ // ── Database connection strings ───────────────────────────────────────────
530
+ // Universal <scheme>://[user]:<password>@<host> shape. Covers the gap
531
+ // vendor-prefix patterns (AWS / GitHub / Stripe / …) leave open. Matches
532
+ // the whole URL so maskSecret produces `<scheme>...:****@...<host>` —
533
+ // the password value never appears in the redacted sample.
534
+ //
535
+ // Schemes covered: redis, rediss (TLS), postgres, postgresql,
536
+ // mongodb, mongodb+srv, mysql, mariadb, amqp, amqps, kafka,
537
+ // clickhouse, cassandra. HTTP(S) / FTP / SSH are intentionally
538
+ // excluded — they're not database URLs and adding them would
539
+ // create false positives on every basic-auth URL in the wild.
540
+ //
541
+ // Requires `:password@` (4+ char password) so user-only URLs like
542
+ // `redis://user@host` don't match. Stopwords ('your', '${', '<your',
543
+ // 'placeholder', 'changeme', etc.) keep doc/README scans clean.
544
+ {
545
+ name: "Database Connection String",
546
+ regex: /\b(redis|rediss|postgres|postgresql|mongodb|mongodb\+srv|mysql|mariadb|amqp|amqps|kafka|clickhouse|cassandra):\/\/[^:/\s@]*:[^@\s]{4,}@[^\s/]+/,
547
+ severity: "block",
548
+ keywords: [
549
+ "redis://",
550
+ "rediss://",
551
+ "postgres://",
552
+ "postgresql://",
553
+ "mongodb://",
554
+ "mongodb+srv://",
555
+ "mysql://",
556
+ "mariadb://",
557
+ "amqp://",
558
+ "amqps://",
559
+ "kafka://",
560
+ "clickhouse://",
561
+ "cassandra://"
562
+ ],
563
+ minEntropy: 3
528
564
  }
529
565
  ];
530
566
  var DLP_PATTERNS_GLOBAL = DLP_PATTERNS.map(
@@ -923,7 +959,7 @@ var SENSITIVE_PATH_RULES = [
923
959
  },
924
960
  {
925
961
  // Mirrors the JSON shield's `.env` pattern (project-jail.json's
926
- // review-read-env-any-tool) so the AST FS-op path catches the
962
+ // block-read-env-any-tool) so the AST FS-op path catches the
927
963
  // same set the regex shield does — including Next.js / Vite's
928
964
  // `.env.<env>.local` double-suffix overrides which are commonly
929
965
  // gitignored AND commonly contain real secrets.
@@ -2435,7 +2471,7 @@ var project_jail_default = {
2435
2471
  {
2436
2472
  field: "command",
2437
2473
  op: "matches",
2438
- value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type)\\s+.*?\\.ssh[\\/\\\\]",
2474
+ value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type|grep|egrep|fgrep|rg|ag|ack|awk|gawk|sed|cut|tr|jq|yq|od|xxd|hexdump|strings|sort|uniq|tac|nl|dd)\\s+.*?\\.ssh[\\/\\\\]",
2439
2475
  flags: "i"
2440
2476
  }
2441
2477
  ],
@@ -2449,7 +2485,7 @@ var project_jail_default = {
2449
2485
  {
2450
2486
  field: "command",
2451
2487
  op: "matches",
2452
- value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type)\\s+.*?\\.aws[\\/\\\\]",
2488
+ value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type|grep|egrep|fgrep|rg|ag|ack|awk|gawk|sed|cut|tr|jq|yq|od|xxd|hexdump|strings|sort|uniq|tac|nl|dd)\\s+.*?\\.aws[\\/\\\\]",
2453
2489
  flags: "i"
2454
2490
  }
2455
2491
  ],
@@ -2463,7 +2499,7 @@ var project_jail_default = {
2463
2499
  {
2464
2500
  field: "command",
2465
2501
  op: "matches",
2466
- value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type)\\s+.*\\.env(\\.local|\\.production|\\.staging)?\\b",
2502
+ value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type|grep|egrep|fgrep|rg|ag|ack|awk|gawk|sed|cut|tr|jq|yq|od|xxd|hexdump|strings|sort|uniq|tac|nl|dd)\\s+.*?\\.env(\\.(local|production|staging|development|production\\.local|staging\\.local|development\\.local))?(?=\\s|$|[;&|>)<])",
2467
2503
  flags: "i"
2468
2504
  }
2469
2505
  ],
@@ -2477,7 +2513,7 @@ var project_jail_default = {
2477
2513
  {
2478
2514
  field: "command",
2479
2515
  op: "matches",
2480
- value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type)\\s+.*(credentials\\.json|\\.netrc|\\.npmrc|\\.docker[\\/\\\\]config\\.json|gcloud[\\/\\\\]credentials)",
2516
+ value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type|grep|egrep|fgrep|rg|ag|ack|awk|gawk|sed|cut|tr|jq|yq|od|xxd|hexdump|strings|sort|uniq|tac|nl|dd)\\s+.*(credentials\\.json|\\.netrc|\\.npmrc|\\.docker[\\/\\\\]config\\.json|gcloud[\\/\\\\]credentials)",
2481
2517
  flags: "i"
2482
2518
  }
2483
2519
  ],
@@ -2513,7 +2549,7 @@ var project_jail_default = {
2513
2549
  reason: "Reading AWS credentials is blocked by project-jail shield"
2514
2550
  },
2515
2551
  {
2516
- name: "shield:project-jail:review-read-env-any-tool",
2552
+ name: "shield:project-jail:block-read-env-any-tool",
2517
2553
  tool: "*",
2518
2554
  conditions: [
2519
2555
  {
@@ -2523,8 +2559,8 @@ var project_jail_default = {
2523
2559
  flags: "i"
2524
2560
  }
2525
2561
  ],
2526
- verdict: "review",
2527
- reason: "Reading .env files requires approval (project-jail shield)"
2562
+ verdict: "block",
2563
+ reason: "Reading .env files is blocked by project-jail shield"
2528
2564
  },
2529
2565
  {
2530
2566
  name: "shield:project-jail:review-read-credentials-any-tool",
package/dist/index.mjs CHANGED
@@ -426,6 +426,42 @@ var DLP_PATTERNS = [
426
426
  regex: /\bAGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JNLH]{58}\b/,
427
427
  severity: "block",
428
428
  keywords: ["age-secret-key-"]
429
+ },
430
+ // ── Database connection strings ───────────────────────────────────────────
431
+ // Universal <scheme>://[user]:<password>@<host> shape. Covers the gap
432
+ // vendor-prefix patterns (AWS / GitHub / Stripe / …) leave open. Matches
433
+ // the whole URL so maskSecret produces `<scheme>...:****@...<host>` —
434
+ // the password value never appears in the redacted sample.
435
+ //
436
+ // Schemes covered: redis, rediss (TLS), postgres, postgresql,
437
+ // mongodb, mongodb+srv, mysql, mariadb, amqp, amqps, kafka,
438
+ // clickhouse, cassandra. HTTP(S) / FTP / SSH are intentionally
439
+ // excluded — they're not database URLs and adding them would
440
+ // create false positives on every basic-auth URL in the wild.
441
+ //
442
+ // Requires `:password@` (4+ char password) so user-only URLs like
443
+ // `redis://user@host` don't match. Stopwords ('your', '${', '<your',
444
+ // 'placeholder', 'changeme', etc.) keep doc/README scans clean.
445
+ {
446
+ name: "Database Connection String",
447
+ regex: /\b(redis|rediss|postgres|postgresql|mongodb|mongodb\+srv|mysql|mariadb|amqp|amqps|kafka|clickhouse|cassandra):\/\/[^:/\s@]*:[^@\s]{4,}@[^\s/]+/,
448
+ severity: "block",
449
+ keywords: [
450
+ "redis://",
451
+ "rediss://",
452
+ "postgres://",
453
+ "postgresql://",
454
+ "mongodb://",
455
+ "mongodb+srv://",
456
+ "mysql://",
457
+ "mariadb://",
458
+ "amqp://",
459
+ "amqps://",
460
+ "kafka://",
461
+ "clickhouse://",
462
+ "cassandra://"
463
+ ],
464
+ minEntropy: 3
429
465
  }
430
466
  ];
431
467
  var DLP_PATTERNS_GLOBAL = DLP_PATTERNS.map(
@@ -824,7 +860,7 @@ var SENSITIVE_PATH_RULES = [
824
860
  },
825
861
  {
826
862
  // Mirrors the JSON shield's `.env` pattern (project-jail.json's
827
- // review-read-env-any-tool) so the AST FS-op path catches the
863
+ // block-read-env-any-tool) so the AST FS-op path catches the
828
864
  // same set the regex shield does — including Next.js / Vite's
829
865
  // `.env.<env>.local` double-suffix overrides which are commonly
830
866
  // gitignored AND commonly contain real secrets.
@@ -2336,7 +2372,7 @@ var project_jail_default = {
2336
2372
  {
2337
2373
  field: "command",
2338
2374
  op: "matches",
2339
- value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type)\\s+.*?\\.ssh[\\/\\\\]",
2375
+ value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type|grep|egrep|fgrep|rg|ag|ack|awk|gawk|sed|cut|tr|jq|yq|od|xxd|hexdump|strings|sort|uniq|tac|nl|dd)\\s+.*?\\.ssh[\\/\\\\]",
2340
2376
  flags: "i"
2341
2377
  }
2342
2378
  ],
@@ -2350,7 +2386,7 @@ var project_jail_default = {
2350
2386
  {
2351
2387
  field: "command",
2352
2388
  op: "matches",
2353
- value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type)\\s+.*?\\.aws[\\/\\\\]",
2389
+ value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type|grep|egrep|fgrep|rg|ag|ack|awk|gawk|sed|cut|tr|jq|yq|od|xxd|hexdump|strings|sort|uniq|tac|nl|dd)\\s+.*?\\.aws[\\/\\\\]",
2354
2390
  flags: "i"
2355
2391
  }
2356
2392
  ],
@@ -2364,7 +2400,7 @@ var project_jail_default = {
2364
2400
  {
2365
2401
  field: "command",
2366
2402
  op: "matches",
2367
- value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type)\\s+.*\\.env(\\.local|\\.production|\\.staging)?\\b",
2403
+ value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type|grep|egrep|fgrep|rg|ag|ack|awk|gawk|sed|cut|tr|jq|yq|od|xxd|hexdump|strings|sort|uniq|tac|nl|dd)\\s+.*?\\.env(\\.(local|production|staging|development|production\\.local|staging\\.local|development\\.local))?(?=\\s|$|[;&|>)<])",
2368
2404
  flags: "i"
2369
2405
  }
2370
2406
  ],
@@ -2378,7 +2414,7 @@ var project_jail_default = {
2378
2414
  {
2379
2415
  field: "command",
2380
2416
  op: "matches",
2381
- value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type)\\s+.*(credentials\\.json|\\.netrc|\\.npmrc|\\.docker[\\/\\\\]config\\.json|gcloud[\\/\\\\]credentials)",
2417
+ value: "(cat|less|head|tail|bat|more|open|print|nano|vim|vi|emacs|code|type|grep|egrep|fgrep|rg|ag|ack|awk|gawk|sed|cut|tr|jq|yq|od|xxd|hexdump|strings|sort|uniq|tac|nl|dd)\\s+.*(credentials\\.json|\\.netrc|\\.npmrc|\\.docker[\\/\\\\]config\\.json|gcloud[\\/\\\\]credentials)",
2382
2418
  flags: "i"
2383
2419
  }
2384
2420
  ],
@@ -2414,7 +2450,7 @@ var project_jail_default = {
2414
2450
  reason: "Reading AWS credentials is blocked by project-jail shield"
2415
2451
  },
2416
2452
  {
2417
- name: "shield:project-jail:review-read-env-any-tool",
2453
+ name: "shield:project-jail:block-read-env-any-tool",
2418
2454
  tool: "*",
2419
2455
  conditions: [
2420
2456
  {
@@ -2424,8 +2460,8 @@ var project_jail_default = {
2424
2460
  flags: "i"
2425
2461
  }
2426
2462
  ],
2427
- verdict: "review",
2428
- reason: "Reading .env files requires approval (project-jail shield)"
2463
+ verdict: "block",
2464
+ reason: "Reading .env files is blocked by project-jail shield"
2429
2465
  },
2430
2466
  {
2431
2467
  name: "shield:project-jail:review-read-credentials-any-tool",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node9/policy-engine",
3
- "version": "1.5.0",
3
+ "version": "1.27.0",
4
4
  "description": "Shared policy evaluation engine for node9 — DLP, smart rules, AST shell parsing, shields, loop detection. Pure functions, no I/O. Used by both node9-proxy and the node9 SaaS firewall.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://node9.ai",