@rexymayderio/sentinel 0.1.1 → 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 (42) hide show
  1. package/README.md +20 -6
  2. package/dist/analyzers/install-script-analyzer.js +2 -2
  3. package/dist/analyzers/install-script-analyzer.js.map +1 -1
  4. package/dist/analyzers/match-evidence.d.ts +6 -1
  5. package/dist/analyzers/match-evidence.d.ts.map +1 -1
  6. package/dist/analyzers/match-evidence.js +10 -3
  7. package/dist/analyzers/match-evidence.js.map +1 -1
  8. package/dist/analyzers/network-analyzer.d.ts.map +1 -1
  9. package/dist/analyzers/network-analyzer.js +85 -4
  10. package/dist/analyzers/network-analyzer.js.map +1 -1
  11. package/dist/analyzers/static-code-analyzer.d.ts.map +1 -1
  12. package/dist/analyzers/static-code-analyzer.js +4 -2
  13. package/dist/analyzers/static-code-analyzer.js.map +1 -1
  14. package/dist/analyzers/strip-comments.d.ts +9 -0
  15. package/dist/analyzers/strip-comments.d.ts.map +1 -0
  16. package/dist/analyzers/strip-comments.js +86 -0
  17. package/dist/analyzers/strip-comments.js.map +1 -0
  18. package/dist/analyzers/test-path.d.ts +7 -3
  19. package/dist/analyzers/test-path.d.ts.map +1 -1
  20. package/dist/analyzers/test-path.js +40 -25
  21. package/dist/analyzers/test-path.js.map +1 -1
  22. package/dist/cli/index.js +7 -5
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/core/sentinel.d.ts +1 -0
  25. package/dist/core/sentinel.d.ts.map +1 -1
  26. package/dist/core/sentinel.js +28 -20
  27. package/dist/core/sentinel.js.map +1 -1
  28. package/dist/engine/default-policy.d.ts +5 -0
  29. package/dist/engine/default-policy.d.ts.map +1 -1
  30. package/dist/engine/default-policy.js.map +1 -1
  31. package/dist/engine/policy-engine.js +3 -3
  32. package/dist/engine/policy-engine.js.map +1 -1
  33. package/dist/engine/risk-calculator.d.ts +1 -5
  34. package/dist/engine/risk-calculator.d.ts.map +1 -1
  35. package/dist/engine/risk-calculator.js +2 -6
  36. package/dist/engine/risk-calculator.js.map +1 -1
  37. package/dist/mcp/server.js +4 -3
  38. package/dist/mcp/server.js.map +1 -1
  39. package/dist/report/report-generator.js +1 -1
  40. package/dist/report/report-generator.js.map +1 -1
  41. package/package.json +1 -1
  42. package/skills/sentinel/SKILL.md +83 -54
package/README.md CHANGED
@@ -4,8 +4,15 @@
4
4
 
5
5
  Sentinel sits between an AI agent (or a human) and any installer. Nothing installs until the target has been **acquired (download-only, never executed)**, **analyzed**, **risk-scored**, **policy-checked**, and **explicitly approved**.
6
6
 
7
- ```
8
- AI / User -> Sentinel -> Acquire -> Analyze -> Score -> Policy -> Approve -> Install
7
+ ```mermaid
8
+ flowchart TD
9
+ A[AI / User] --> B[Sentinel]
10
+ B --> C[Acquire]
11
+ C --> D[Analyze]
12
+ D --> E[Score]
13
+ E --> F[Policy]
14
+ F --> G[Approve]
15
+ G --> H[Install]
9
16
  ```
10
17
 
11
18
  The installer never runs directly. Acquirers only download and read files; install scripts are never executed during analysis.
@@ -55,7 +62,7 @@ sentinel verify npm express --markdown
55
62
  # Custom policy file
56
63
  sentinel verify npm express --policy ./policy.json
57
64
 
58
- # Score test/fixture findings at full weight (default: down-weighted)
65
+ # Scan test/fixture files with the full ruleset (default: secrets + malware only)
59
66
  sentinel verify local ./my-project --score-tests
60
67
 
61
68
  # CLI help
@@ -105,7 +112,7 @@ MCP tools: `verify_package`, `verify_repository`, `verify_skill`, `verify_mcp`,
105
112
 
106
113
  ### Agent Skill
107
114
 
108
- Install the Sentinel agent skill so your AI assistant intercepts install requests, verifies via the MCP above, explains risks, and only installs after approval.
115
+ Install the [Sentinel agent skill](https://github.com/RexySaragih/sentinel/blob/master/skills/sentinel/SKILL.md) so your AI assistant intercepts install requests, verifies via the MCP above, explains risks, and only installs after approval.
109
116
 
110
117
  Copy or symlink [skills/sentinel/SKILL.md](skills/sentinel/SKILL.md) into your agent's skills directory (e.g. `~/.cursor/skills/sentinel/SKILL.md` for Cursor).
111
118
 
@@ -139,7 +146,14 @@ Each finding has a severity. The Risk Calculator sums severity weights, subtract
139
146
 
140
147
  Positive signals (verified publisher, long history, etc.) each subtract `5`, capped at `-30` total.
141
148
 
142
- **Test/fixture code** is detected by path (`test/`, `tests/`, `__tests__/`, `fixtures/`, `*.test.*`, `*.spec.*`, etc.). Findings in those files are still reported (tagged `[test]` in terminal output, `isTest: true` in JSON) but contribute only **10%** of their severity weight by default. They also do not drive permission detection. Use `--score-tests` or set `scoreTestCodeFully: true` in policy to score them at full weight.
149
+ **Test/fixture code** is detected by path (`test/`, `tests/`, `__tests__/`, `fixtures/`, `*.test.*`, `*.spec.*`, etc.) and scanned with a **narrower ruleset** than production code. Everyday dev patterns (`child_process`, `spawn`, `eval`, dynamic imports, `rm -rf`, ...) are expected in tests and are **not** flagged there. Instead, test files are checked only for the things that genuinely matter in tests the places malware likes to hide:
150
+
151
+ - **Leaked secrets** (AWS/GCP/OpenAI keys, private keys, tokens, ...)
152
+ - **Malware signatures**: remote payload delivery (`curl … | sh`, `wget … | sh`), crypto miners, UPX-packed blobs
153
+ - **Exfiltration / C2 channels**: Discord/Telegram webhooks, Pastebin, ngrok, Cloudflare tunnels, `.onion`, dynamic DNS
154
+ - **Prompt-injection attacks** hidden in fixtures
155
+
156
+ Findings that survive this filter are real, so they are reported (tagged `[test-file]` in terminal output, `isTest: true` in JSON) and counted at **full weight** in the risk score and policy. Use `--score-tests` (or set `scoreTestCodeFully: true` in policy) to scan test files with the full production ruleset instead.
143
157
 
144
158
  The final score maps to a **risk level**:
145
159
 
@@ -246,7 +260,7 @@ Pass a JSON file via `--policy <file>` to override defaults (`src/engine/default
246
260
  | `warnOnInstallScript` | boolean | `true` | Install scripts -> `WARN`. |
247
261
  | `warnOnShellAccess` | boolean | `true` | Shell access -> `WARN`/`REQUIRE_APPROVAL`. |
248
262
  | `allowOverrides` | boolean | `true` | Allow human overrides of non-`BLOCK` decisions. |
249
- | `scoreTestCodeFully` | boolean | `false` | When `true`, findings in test/fixture paths score at full weight. |
263
+ | `scoreTestCodeFully` | boolean | `false` | When `false`, test/fixture files are scanned only for leaked secrets and malware signatures. When `true`, they are scanned with the full production ruleset. |
250
264
 
251
265
  Example `policy.json`:
252
266
 
@@ -26,9 +26,9 @@ export class InstallScriptAnalyzer {
26
26
  continue;
27
27
  findings.push(createFinding({
28
28
  category: 'install-script',
29
- severity: 'MEDIUM',
29
+ severity: 'LOW',
30
30
  title: `Install script: ${key}`,
31
- description: `Package defines a ${key} script`,
31
+ description: `Package defines a ${key} script - it runs automatically on install`,
32
32
  ruleId: `script-${key}`,
33
33
  evidence: script,
34
34
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"install-script-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/install-script-analyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install-script-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/install-script-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,MAAM,mBAAmB,GAAG,CAAC,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;AAC9F,MAAM,0BAA0B,GAAG;IACjC,EAAE,OAAO,EAAE,gCAAgC,EAAE,QAAQ,EAAE,UAAmB,EAAE,KAAK,EAAE,sCAAsC,EAAE;IAC3H,EAAE,OAAO,EAAE,gCAAgC,EAAE,QAAQ,EAAE,UAAmB,EAAE,KAAK,EAAE,sCAAsC,EAAE;IAC3H,EAAE,OAAO,EAAE,uCAAuC,EAAE,QAAQ,EAAE,MAAe,EAAE,KAAK,EAAE,0CAA0C,EAAE;IAClI,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAe,EAAE,KAAK,EAAE,wBAAwB,EAAE;IACrF,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAiB,EAAE,KAAK,EAAE,4BAA4B,EAAE;IAC7F,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAe,EAAE,KAAK,EAAE,0BAA0B,EAAE;IACtF,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAiB,EAAE,KAAK,EAAE,uBAAuB,EAAE;IACnF,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAiB,EAAE,KAAK,EAAE,4BAA4B,EAAE;IAC5F,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAiB,EAAE,KAAK,EAAE,+BAA+B,EAAE;IAClG,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAiB,EAAE,KAAK,EAAE,+BAA+B,EAAE;CACnG,CAAC;AAEF,MAAM,OAAO,qBAAqB;IACvB,EAAE,GAAG,gBAAgB,CAAC;IAE/B,QAAQ,CAAC,GAAoB;QAC3B,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAoB;QAChC,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;QAEpD,KAAK,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,MAAM;gBAAE,SAAS;YAEtB,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;gBAC1B,QAAQ,EAAE,gBAAgB;gBAC1B,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,mBAAmB,GAAG,EAAE;gBAC/B,WAAW,EAAE,qBAAqB,GAAG,4CAA4C;gBACjF,MAAM,EAAE,UAAU,GAAG,EAAE;gBACvB,QAAQ,EAAE,MAAM;aACjB,CAAC,CAAC,CAAC;YAEJ,KAAK,MAAM,KAAK,IAAI,0BAA0B,EAAE,CAAC;gBAC/C,KAAK,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;gBAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC/B,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;wBAC1B,QAAQ,EAAE,gBAAgB;wBAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,WAAW,EAAE,wBAAwB,GAAG,YAAY,KAAK,CAAC,KAAK,EAAE;wBACjE,MAAM,EAAE,aAAa,GAAG,EAAE;wBAC1B,QAAQ,EAAE,MAAM;qBACjB,CAAC,CAAC,CAAC;gBACN,CAAC;YACH,CAAC;QACH,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACtC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,EAAE,CAAC;gBAClD,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;oBAC1B,QAAQ,EAAE,gBAAgB;oBAC1B,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,gCAAgC;oBACvC,WAAW,EAAE,8BAA8B,IAAI,CAAC,IAAI,EAAE;oBACtD,MAAM,EAAE,mBAAmB;oBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC,CAAC,CAAC;YACN,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
@@ -1,5 +1,10 @@
1
1
  export declare const MAX_EVIDENCE_LENGTH = 120;
2
- export declare function findMatchingLine(content: string, pattern: RegExp): {
2
+ /**
3
+ * Finds the first line matching `pattern`. Matching runs against `searchContent`
4
+ * (which may have comments masked out), while the returned evidence is taken from
5
+ * `displayContent` so the user still sees the real source line.
6
+ */
7
+ export declare function findMatchingLine(searchContent: string, pattern: RegExp, displayContent?: string): {
3
8
  line: number;
4
9
  evidence: string;
5
10
  } | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"match-evidence.d.ts","sourceRoot":"","sources":["../../src/analyzers/match-evidence.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAYhD"}
1
+ {"version":3,"file":"match-evidence.d.ts","sourceRoot":"","sources":["../../src/analyzers/match-evidence.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,MAAsB,GACrC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAchD"}
@@ -1,12 +1,19 @@
1
1
  export const MAX_EVIDENCE_LENGTH = 120;
2
- export function findMatchingLine(content, pattern) {
3
- const lines = content.split('\n');
2
+ /**
3
+ * Finds the first line matching `pattern`. Matching runs against `searchContent`
4
+ * (which may have comments masked out), while the returned evidence is taken from
5
+ * `displayContent` so the user still sees the real source line.
6
+ */
7
+ export function findMatchingLine(searchContent, pattern, displayContent = searchContent) {
8
+ const lines = searchContent.split('\n');
9
+ const displayLines = displayContent.split('\n');
4
10
  for (let i = 0; i < lines.length; i++) {
5
11
  pattern.lastIndex = 0;
6
12
  if (pattern.test(lines[i])) {
13
+ const source = displayLines[i] ?? lines[i];
7
14
  return {
8
15
  line: i + 1,
9
- evidence: lines[i].trim().slice(0, MAX_EVIDENCE_LENGTH),
16
+ evidence: source.trim().slice(0, MAX_EVIDENCE_LENGTH),
10
17
  };
11
18
  }
12
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"match-evidence.js","sourceRoot":"","sources":["../../src/analyzers/match-evidence.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,OAAe;IAEf,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QACtB,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;YAC5B,OAAO;gBACL,IAAI,EAAE,CAAC,GAAG,CAAC;gBACX,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC;aACzD,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"match-evidence.js","sourceRoot":"","sources":["../../src/analyzers/match-evidence.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,aAAqB,EACrB,OAAe,EACf,iBAAyB,aAAa;IAEtC,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QACtB,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC;YAC5C,OAAO;gBACL,IAAI,EAAE,CAAC,GAAG,CAAC;gBACX,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC;aACtD,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"network-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/network-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM/D,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,QAAQ,CAAC,EAAE,aAAa;IAExB,QAAQ,IAAI,OAAO;IAIb,OAAO,CAAC,GAAG,EAAE,eAAe;CAuCnC"}
1
+ {"version":3,"file":"network-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/network-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AA2D/D,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,QAAQ,CAAC,EAAE,aAAa;IAExB,QAAQ,IAAI,OAAO;IAIb,OAAO,CAAC,GAAG,EAAE,eAAe;CA+DnC"}
@@ -1,7 +1,67 @@
1
1
  import { createFinding } from '../domain/finding.js';
2
2
  import { findMatchingLine } from './match-evidence.js';
3
+ import { stripComments } from './strip-comments.js';
3
4
  import { NETWORK_RULES } from './rules/index.js';
5
+ const HARDCODED_IP_RULE_ID = 'hardcoded-ip';
6
+ const IPV4_PATTERN = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
4
7
  const PRIVATE_IP_PATTERN = /\b(?:10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(?:1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/g;
8
+ const MAX_OCTET = 255;
9
+ const DOC_FILE_PATTERN = /(?:^|\/)(?:README|CHANGELOG|HISTORY|CONTRIBUTING|LICENSE|NOTICE)(?:\.\w+)?$|\.(?:md|mdx|markdown|rst|txt|adoc)$/i;
10
+ function isDocumentationFile(path) {
11
+ return DOC_FILE_PATTERN.test(path);
12
+ }
13
+ function parseOctets(ip) {
14
+ const octets = ip.split('.').map((part) => Number(part));
15
+ if (octets.length !== 4)
16
+ return undefined;
17
+ if (octets.some((n) => !Number.isInteger(n) || n < 0 || n > MAX_OCTET))
18
+ return undefined;
19
+ return octets;
20
+ }
21
+ /**
22
+ * A routable public IPv4 address - the only kind worth flagging as a hardcoded
23
+ * endpoint (potential C2 / exfil host). Loopback, private, link-local, CGNAT,
24
+ * documentation (RFC 5737), multicast, and reserved ranges are excluded: they
25
+ * are either benign examples or covered by the lower-severity private-ip rule.
26
+ */
27
+ function isRoutablePublicIp(ip) {
28
+ const octets = parseOctets(ip);
29
+ if (!octets)
30
+ return false;
31
+ const [a, b, c] = octets;
32
+ if (a === 0 || a === 127)
33
+ return false;
34
+ if (a === 10)
35
+ return false;
36
+ if (a === 172 && b >= 16 && b <= 31)
37
+ return false;
38
+ if (a === 192 && b === 168)
39
+ return false;
40
+ if (a === 169 && b === 254)
41
+ return false;
42
+ if (a === 100 && b >= 64 && b <= 127)
43
+ return false;
44
+ if (a === 192 && b === 0 && c === 2)
45
+ return false;
46
+ if (a === 198 && b === 51 && c === 100)
47
+ return false;
48
+ if (a === 203 && b === 0 && c === 113)
49
+ return false;
50
+ if (a >= 224)
51
+ return false;
52
+ return true;
53
+ }
54
+ function findRoutablePublicIp(content) {
55
+ IPV4_PATTERN.lastIndex = 0;
56
+ for (const match of content.matchAll(IPV4_PATTERN)) {
57
+ if (isRoutablePublicIp(match[0]))
58
+ return match[0];
59
+ }
60
+ return undefined;
61
+ }
62
+ function escapeRegExp(value) {
63
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
64
+ }
5
65
  export class NetworkAnalyzer {
6
66
  id = 'network';
7
67
  supports() {
@@ -10,10 +70,13 @@ export class NetworkAnalyzer {
10
70
  async analyze(ctx) {
11
71
  const findings = [];
12
72
  for (const file of ctx.artifact.files) {
73
+ const scanContent = stripComments(file.content, file.path);
13
74
  for (const rule of NETWORK_RULES) {
75
+ if (rule.id === HARDCODED_IP_RULE_ID)
76
+ continue;
14
77
  rule.pattern.lastIndex = 0;
15
- if (rule.pattern.test(file.content)) {
16
- const match = findMatchingLine(file.content, rule.pattern);
78
+ if (rule.pattern.test(scanContent)) {
79
+ const match = findMatchingLine(scanContent, rule.pattern, file.content);
17
80
  findings.push(createFinding({
18
81
  category: 'network',
19
82
  severity: rule.severity,
@@ -26,9 +89,27 @@ export class NetworkAnalyzer {
26
89
  }));
27
90
  }
28
91
  }
92
+ const publicIp = findRoutablePublicIp(scanContent);
93
+ if (publicIp) {
94
+ const match = findMatchingLine(scanContent, new RegExp(escapeRegExp(publicIp)), file.content);
95
+ findings.push(createFinding({
96
+ category: 'network',
97
+ severity: 'MEDIUM',
98
+ title: 'Hardcoded IP',
99
+ description: `Hardcoded public IP address detected: ${publicIp}`,
100
+ ruleId: HARDCODED_IP_RULE_ID,
101
+ file: file.path,
102
+ line: match?.line,
103
+ evidence: match?.evidence,
104
+ }));
105
+ }
106
+ // Private/loopback IPs are only a (low) signal in real code, never in docs
107
+ // or test fixtures where localhost examples are routine.
29
108
  PRIVATE_IP_PATTERN.lastIndex = 0;
30
- if (PRIVATE_IP_PATTERN.test(file.content) && !file.path.includes('test')) {
31
- const match = findMatchingLine(file.content, PRIVATE_IP_PATTERN);
109
+ if (!isDocumentationFile(file.path) &&
110
+ !file.path.includes('test') &&
111
+ PRIVATE_IP_PATTERN.test(scanContent)) {
112
+ const match = findMatchingLine(scanContent, PRIVATE_IP_PATTERN, file.content);
32
113
  findings.push(createFinding({
33
114
  category: 'network',
34
115
  severity: 'LOW',
@@ -1 +1 @@
1
- {"version":3,"file":"network-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/network-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,kBAAkB,GAAG,8IAA8I,CAAC;AAE1K,MAAM,OAAO,eAAe;IACjB,EAAE,GAAG,SAAS,CAAC;IAExB,QAAQ;QACN,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAoB;QAChC,MAAM,QAAQ,GAAG,EAAE,CAAC;QAEpB,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACtC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;gBACjC,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;gBAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;oBACpC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC3D,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;wBAC1B,QAAQ,EAAE,SAAS;wBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC7B,MAAM,EAAE,IAAI,CAAC,EAAE;wBACf,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,IAAI,EAAE,KAAK,EAAE,IAAI;wBACjB,QAAQ,EAAE,KAAK,EAAE,QAAQ;qBAC1B,CAAC,CAAC,CAAC;gBACN,CAAC;YACH,CAAC;YAED,kBAAkB,CAAC,SAAS,GAAG,CAAC,CAAC;YACjC,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzE,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;gBACjE,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;oBAC1B,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,KAAK;oBACf,KAAK,EAAE,sBAAsB;oBAC7B,WAAW,EAAE,qCAAqC,IAAI,CAAC,IAAI,EAAE;oBAC7D,MAAM,EAAE,YAAY;oBACpB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,IAAI,EAAE,KAAK,EAAE,IAAI;oBACjB,QAAQ,EAAE,KAAK,EAAE,QAAQ;iBAC1B,CAAC,CAAC,CAAC;YACN,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
1
+ {"version":3,"file":"network-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/network-analyzer.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"static-code-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/static-code-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAmB/D,qBAAa,kBAAmB,YAAW,QAAQ;IACjD,QAAQ,CAAC,EAAE,iBAAiB;IAE5B,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAIjC,OAAO,CAAC,GAAG,EAAE,eAAe;CAmDnC"}
1
+ {"version":3,"file":"static-code-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/static-code-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAoB/D,qBAAa,kBAAmB,YAAW,QAAQ;IACjD,QAAQ,CAAC,EAAE,iBAAiB;IAE5B,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAIjC,OAAO,CAAC,GAAG,EAAE,eAAe;CAqDnC"}
@@ -1,5 +1,6 @@
1
1
  import { createFinding } from '../domain/finding.js';
2
2
  import { findMatchingLine } from './match-evidence.js';
3
+ import { stripComments } from './strip-comments.js';
3
4
  import { DANGEROUS_API_RULES, OBFUSCATION_RULES } from './rules/index.js';
4
5
  const CODE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.py', '.go', '.rs', '.sh', '.bash', '.lua'];
5
6
  function calculateEntropy(content) {
@@ -23,10 +24,11 @@ export class StaticCodeAnalyzer {
23
24
  const findings = [];
24
25
  const codeFiles = ctx.artifact.files.filter((f) => CODE_EXTENSIONS.some((ext) => f.path.endsWith(ext)));
25
26
  for (const file of codeFiles) {
27
+ const codeOnly = stripComments(file.content, file.path);
26
28
  for (const rule of [...DANGEROUS_API_RULES, ...OBFUSCATION_RULES]) {
27
29
  rule.pattern.lastIndex = 0;
28
- if (rule.pattern.test(file.content)) {
29
- const match = findMatchingLine(file.content, rule.pattern);
30
+ if (rule.pattern.test(codeOnly)) {
31
+ const match = findMatchingLine(codeOnly, rule.pattern, file.content);
30
32
  findings.push(createFinding({
31
33
  category: 'static-code',
32
34
  severity: rule.severity,
@@ -1 +1 @@
1
- {"version":3,"file":"static-code-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/static-code-analyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"static-code-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/static-code-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1E,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAEpH,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC;QACjC,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,OAAO,kBAAkB;IACpB,EAAE,GAAG,aAAa,CAAC;IAE5B,QAAQ,CAAC,GAAoB;QAC3B,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7F,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAoB;QAChC,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAChD,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CACpD,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAExD,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,mBAAmB,EAAE,GAAG,iBAAiB,CAAC,EAAE,CAAC;gBAClE,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;gBAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChC,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;oBAErE,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;wBAC1B,QAAQ,EAAE,aAAa;wBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC7B,MAAM,EAAE,IAAI,CAAC,EAAE;wBACf,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,IAAI,EAAE,KAAK,EAAE,IAAI;wBACjB,QAAQ,EAAE,KAAK,EAAE,QAAQ;qBAC1B,CAAC,CAAC,CAAC;gBACN,CAAC;YACH,CAAC;YAED,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBAChE,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;oBAC1B,QAAQ,EAAE,aAAa;oBACvB,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,qBAAqB;oBAC5B,WAAW,EAAE,QAAQ,IAAI,CAAC,IAAI,sBAAsB,IAAI,CAAC,IAAI,oBAAoB;oBACjF,MAAM,EAAE,UAAU;oBAClB,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC,CAAC,CAAC;YACN,CAAC;YAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;YAC/D,IAAI,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC;gBACtC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;oBAC1B,QAAQ,EAAE,aAAa;oBACvB,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,sBAAsB;oBAC7B,WAAW,EAAE,QAAQ,IAAI,CAAC,IAAI,sBAAsB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B;oBAChG,MAAM,EAAE,cAAc;oBACtB,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC,CAAC,CAAC;YACN,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Replaces comment content with spaces while preserving newlines, string
3
+ * literals, and overall character positions. Line numbers and column offsets
4
+ * stay intact so findings still map to the right source location.
5
+ *
6
+ * String-aware: a `//` inside "http://..." is NOT treated as a comment.
7
+ */
8
+ export declare function stripComments(content: string, path: string): string;
9
+ //# sourceMappingURL=strip-comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strip-comments.d.ts","sourceRoot":"","sources":["../../src/analyzers/strip-comments.ts"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAmEnE"}
@@ -0,0 +1,86 @@
1
+ const C_STYLE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.go', '.rs'];
2
+ const HASH_STYLE_EXTENSIONS = ['.py', '.sh', '.bash', '.zsh'];
3
+ const LUA_STYLE_EXTENSIONS = ['.lua'];
4
+ function commentStyleFor(path) {
5
+ const lower = path.toLowerCase();
6
+ if (C_STYLE_EXTENSIONS.some((ext) => lower.endsWith(ext)))
7
+ return 'c';
8
+ if (HASH_STYLE_EXTENSIONS.some((ext) => lower.endsWith(ext)))
9
+ return 'hash';
10
+ if (LUA_STYLE_EXTENSIONS.some((ext) => lower.endsWith(ext)))
11
+ return 'lua';
12
+ return undefined;
13
+ }
14
+ /**
15
+ * Replaces comment content with spaces while preserving newlines, string
16
+ * literals, and overall character positions. Line numbers and column offsets
17
+ * stay intact so findings still map to the right source location.
18
+ *
19
+ * String-aware: a `//` inside "http://..." is NOT treated as a comment.
20
+ */
21
+ export function stripComments(content, path) {
22
+ const style = commentStyleFor(path);
23
+ if (!style)
24
+ return content;
25
+ const out = [];
26
+ let i = 0;
27
+ const n = content.length;
28
+ const isLineComment = (idx) => {
29
+ if (style === 'c' && content[idx] === '/' && content[idx + 1] === '/')
30
+ return 2;
31
+ if (style === 'hash' && content[idx] === '#')
32
+ return 1;
33
+ if (style === 'lua' && content[idx] === '-' && content[idx + 1] === '-')
34
+ return 2;
35
+ return 0;
36
+ };
37
+ while (i < n) {
38
+ const ch = content[i];
39
+ // String literals - copy verbatim, respecting escapes.
40
+ if (ch === '"' || ch === "'" || (style === 'c' && ch === '`')) {
41
+ const quote = ch;
42
+ out.push(ch);
43
+ i++;
44
+ while (i < n) {
45
+ const c = content[i];
46
+ out.push(c === '\n' ? '\n' : c);
47
+ if (c === '\\') {
48
+ if (i + 1 < n) {
49
+ out.push(content[i + 1] === '\n' ? '\n' : content[i + 1]);
50
+ i += 2;
51
+ continue;
52
+ }
53
+ }
54
+ i++;
55
+ if (c === quote)
56
+ break;
57
+ }
58
+ continue;
59
+ }
60
+ // C-style block comment.
61
+ if (style === 'c' && ch === '/' && content[i + 1] === '*') {
62
+ while (i < n && !(content[i] === '*' && content[i + 1] === '/')) {
63
+ out.push(content[i] === '\n' ? '\n' : ' ');
64
+ i++;
65
+ }
66
+ if (i < n) {
67
+ out.push(' ');
68
+ i += 2;
69
+ }
70
+ continue;
71
+ }
72
+ // Line comment - blank out to end of line.
73
+ const lineCommentLen = isLineComment(i);
74
+ if (lineCommentLen > 0) {
75
+ while (i < n && content[i] !== '\n') {
76
+ out.push(' ');
77
+ i++;
78
+ }
79
+ continue;
80
+ }
81
+ out.push(ch);
82
+ i++;
83
+ }
84
+ return out.join('');
85
+ }
86
+ //# sourceMappingURL=strip-comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strip-comments.js","sourceRoot":"","sources":["../../src/analyzers/strip-comments.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,9 @@
1
- /** npm packages where shell/process APIs in lib/ are expected (test runners). */
2
- export declare const TEST_TOOL_PACKAGES: Set<string>;
1
+ import type { Finding } from '../domain/finding.js';
3
2
  export declare function isTestPath(filePath: string): boolean;
4
- export declare function isTestToolShellFinding(packageName: string | undefined, filePath: string | undefined, ruleId: string | undefined): boolean;
3
+ /**
4
+ * Whether a finding is worth surfacing when it lives in a test/fixture file.
5
+ * Leaked secrets and explicit malware signatures qualify; benign dev-pattern
6
+ * findings (shell APIs, dynamic imports, etc.) do not.
7
+ */
8
+ export declare function isTestRelevantFinding(finding: Finding): boolean;
5
9
  //# sourceMappingURL=test-path.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"test-path.d.ts","sourceRoot":"","sources":["../../src/analyzers/test-path.ts"],"names":[],"mappings":"AAkBA,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,aAU7B,CAAC;AAqBH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAYpD;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,OAAO,CAKT"}
1
+ {"version":3,"file":"test-path.d.ts","sourceRoot":"","sources":["../../src/analyzers/test-path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AA4DpD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAYpD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAI/D"}
@@ -15,26 +15,35 @@ const TEST_DIR_SEGMENTS = new Set([
15
15
  'test-runner',
16
16
  'testing',
17
17
  ]);
18
- /** npm packages where shell/process APIs in lib/ are expected (test runners). */
19
- export const TEST_TOOL_PACKAGES = new Set([
20
- 'test',
21
- 'jest',
22
- 'vitest',
23
- 'mocha',
24
- 'tap',
25
- 'ava',
26
- 'jasmine',
27
- 'playwright',
28
- 'cypress',
29
- ]);
30
- const SHELL_RULE_IDS = new Set([
31
- 'spawn',
32
- 'exec',
33
- 'exec-sync-file',
34
- 'child-process',
35
- 'os-system',
36
- 'subprocess',
37
- 'powershell',
18
+ /**
19
+ * Rule IDs that stay meaningful inside test/fixture code. Everyday dev patterns
20
+ * (child_process, spawn, eval, dynamic import, ...) are expected in tests and
21
+ * are NOT flagged there - but malware loves to hide in fixtures, so we keep the
22
+ * unambiguous attack signatures: remote payload delivery, miners, packed
23
+ * binaries, exfiltration/C2 channels, and prompt-injection attacks.
24
+ */
25
+ const TEST_MALWARE_RULE_IDS = new Set([
26
+ 'curl-pipe',
27
+ 'wget-pipe',
28
+ 'crypto-miner',
29
+ 'packed-upx',
30
+ 'discord-webhook',
31
+ 'telegram-bot',
32
+ 'pastebin',
33
+ 'ngrok',
34
+ 'cloudflare-tunnel',
35
+ 'tor',
36
+ 'dynamic-dns',
37
+ 'ignore-instructions',
38
+ 'system-prompt-extract',
39
+ 'tool-escalation',
40
+ 'memory-poison',
41
+ 'self-update',
42
+ 'hidden-goal',
43
+ 'jailbreak',
44
+ 'recursive-agent',
45
+ 'fake-success',
46
+ 'activation-phrase',
38
47
  ]);
39
48
  function isTestFileName(name) {
40
49
  const lower = name.toLowerCase();
@@ -53,10 +62,16 @@ export function isTestPath(filePath) {
53
62
  .slice(0, -1)
54
63
  .some((segment) => TEST_DIR_SEGMENTS.has(segment.toLowerCase()));
55
64
  }
56
- export function isTestToolShellFinding(packageName, filePath, ruleId) {
57
- if (!packageName || !filePath || !ruleId || !SHELL_RULE_IDS.has(ruleId)) {
58
- return false;
59
- }
60
- return TEST_TOOL_PACKAGES.has(packageName.toLowerCase()) && isTestPath(filePath);
65
+ /**
66
+ * Whether a finding is worth surfacing when it lives in a test/fixture file.
67
+ * Leaked secrets and explicit malware signatures qualify; benign dev-pattern
68
+ * findings (shell APIs, dynamic imports, etc.) do not.
69
+ */
70
+ export function isTestRelevantFinding(finding) {
71
+ if (finding.positive)
72
+ return true;
73
+ if (finding.category === 'secret')
74
+ return true;
75
+ return finding.ruleId !== undefined && TEST_MALWARE_RULE_IDS.has(finding.ruleId);
61
76
  }
62
77
  //# sourceMappingURL=test-path.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"test-path.js","sourceRoot":"","sources":["../../src/analyzers/test-path.ts"],"names":[],"mappings":"AAAA,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,MAAM;IACN,OAAO;IACP,WAAW;IACX,WAAW;IACX,cAAc;IACd,UAAU;IACV,SAAS;IACT,MAAM;IACN,OAAO;IACP,KAAK;IACL,OAAO;IACP,UAAU;IACV,aAAa;IACb,aAAa;IACb,SAAS;CACV,CAAC,CAAC;AAEH,iFAAiF;AACjF,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;IACxC,MAAM;IACN,MAAM;IACN,QAAQ;IACR,OAAO;IACP,KAAK;IACL,KAAK;IACL,SAAS;IACT,YAAY;IACZ,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,OAAO;IACP,MAAM;IACN,gBAAgB;IAChB,eAAe;IACf,WAAW;IACX,YAAY;IACZ,YAAY;CACb,CAAC,CAAC;AAEH,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,CACL,gCAAgC,CAAC,IAAI,CAAC,KAAK,CAAC;QAC5C,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/B,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAErD,IAAI,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,QAAQ;SACZ,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SACZ,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,WAA+B,EAC/B,QAA4B,EAC5B,MAA0B;IAE1B,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACxE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;AACnF,CAAC"}
1
+ {"version":3,"file":"test-path.js","sourceRoot":"","sources":["../../src/analyzers/test-path.ts"],"names":[],"mappings":"AAEA,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,MAAM;IACN,OAAO;IACP,WAAW;IACX,WAAW;IACX,cAAc;IACd,UAAU;IACV,SAAS;IACT,MAAM;IACN,OAAO;IACP,KAAK;IACL,OAAO;IACP,UAAU;IACV,aAAa;IACb,aAAa;IACb,SAAS;CACV,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,WAAW;IACX,WAAW;IACX,cAAc;IACd,YAAY;IACZ,iBAAiB;IACjB,cAAc;IACd,UAAU;IACV,OAAO;IACP,mBAAmB;IACnB,KAAK;IACL,aAAa;IACb,qBAAqB;IACrB,uBAAuB;IACvB,iBAAiB;IACjB,eAAe;IACf,aAAa;IACb,aAAa;IACb,WAAW;IACX,iBAAiB;IACjB,cAAc;IACd,mBAAmB;CACpB,CAAC,CAAC;AAEH,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,CACL,gCAAgC,CAAC,IAAI,CAAC,KAAK,CAAC;QAC5C,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/B,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAErD,IAAI,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,QAAQ;SACZ,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SACZ,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AACrE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACnF,CAAC"}
package/dist/cli/index.js CHANGED
@@ -66,15 +66,16 @@ program
66
66
  .option('--json', 'Output the full verification report as JSON (machine-readable)')
67
67
  .option('--markdown', 'Output the report as Markdown')
68
68
  .option('--policy <file>', 'Path to a JSON policy file (overrides default thresholds and lists)')
69
- .option('--score-tests', 'Score findings in test/fixture files at full severity (default: down-weighted)')
69
+ .option('--score-tests', 'Scan test/fixture files with the full ruleset (default: secrets and malware only)')
70
70
  .addHelpText('after', `${VERIFY_EXAMPLES}
71
71
  Options (default output is a colored terminal report):
72
72
  --json Structured JSON with findings, risk, policy, permissions, evidence
73
73
  --markdown Markdown table suitable for docs or PR comments
74
74
  --policy Custom policy: blockThreshold, warnThreshold, minConfidence,
75
75
  trustedPublishers, corporateWhitelist, corporateBlacklist, etc.
76
- --score-tests Treat dangerous code in test/fixture files at full weight
77
- (by default such findings are shown but down-weighted)
76
+ --score-tests Scan test/fixture files with the full production ruleset.
77
+ By default tests are only checked for leaked secrets and
78
+ malware signatures (curl|bash, miners, exfiltration, etc.)
78
79
 
79
80
  ${TARGET_TYPES_HELP}`)
80
81
  .action(async (type, target, opts) => {
@@ -109,13 +110,14 @@ program
109
110
  .option('--json', 'Output the verification report as JSON instead of terminal format')
110
111
  .option('--yes', 'Auto-approve installation after verification (cannot override BLOCK)')
111
112
  .option('--policy <file>', 'Path to a JSON policy file (overrides default thresholds and lists)')
112
- .option('--score-tests', 'Score findings in test/fixture files at full severity (default: down-weighted)')
113
+ .option('--score-tests', 'Scan test/fixture files with the full ruleset (default: secrets and malware only)')
113
114
  .addHelpText('after', `${INSTALL_EXAMPLES}
114
115
  Options:
115
116
  --json Output report as JSON (terminal format is default)
116
117
  --yes Skip the interactive [y/N] approval prompt when policy allows it
117
118
  --policy Custom policy file (same fields as verify --policy)
118
- --score-tests Treat dangerous code in test/fixture files at full weight
119
+ --score-tests Scan test/fixture files with the full production ruleset
120
+ (default: tests checked only for secrets and malware)
119
121
 
120
122
  Install behavior by ecosystem:
121
123
  npm npm install <name> --ignore-scripts
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,7 @@ export declare class Sentinel {
24
24
  install(ecosystem: string, raw: string, options?: {
25
25
  forceApprove?: boolean;
26
26
  onVerified?: () => void;
27
+ cwd?: string;
27
28
  }): Promise<InstallResult>;
28
29
  generateReport(report: VerificationReport, format?: ReportFormat): string;
29
30
  private runInstaller;