vanara 0.1.0 → 0.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.
Files changed (195) hide show
  1. package/README.md +14 -0
  2. package/bin/vanara.js +66 -2
  3. package/catalog/agents/api-designer/AGENT.md +140 -0
  4. package/catalog/agents/api-designer/examples/openapi-snippet.yaml +130 -0
  5. package/catalog/agents/api-designer/examples/review-notes.md +61 -0
  6. package/catalog/agents/api-designer/references/contract-and-openapi.md +82 -0
  7. package/catalog/agents/api-designer/references/design-checklist.md +68 -0
  8. package/catalog/agents/api-designer/references/versioning-and-evolution.md +63 -0
  9. package/catalog/agents/api-designer/scripts/lint-openapi.mjs +180 -0
  10. package/catalog/agents/code-reviewer/AGENT.md +168 -0
  11. package/catalog/agents/code-reviewer/examples/pr-comment-template.md +48 -0
  12. package/catalog/agents/code-reviewer/examples/sample-review-output.md +38 -0
  13. package/catalog/agents/code-reviewer/references/review-checklist.md +46 -0
  14. package/catalog/agents/code-reviewer/references/security-review.md +62 -0
  15. package/catalog/agents/code-reviewer/references/severity-rubric.md +63 -0
  16. package/catalog/agents/code-reviewer/scripts/review-guard.mjs +102 -0
  17. package/catalog/agents/debugger/AGENT.md +112 -0
  18. package/catalog/agents/debugger/examples/postmortem-template.md +59 -0
  19. package/catalog/agents/debugger/examples/repro-template.md +50 -0
  20. package/catalog/agents/debugger/references/bisection.md +63 -0
  21. package/catalog/agents/debugger/references/debugging-method.md +57 -0
  22. package/catalog/agents/debugger/references/observability.md +61 -0
  23. package/catalog/agents/debugger/scripts/parse-stacktrace.mjs +109 -0
  24. package/catalog/agents/pr-summarizer/AGENT.md +156 -0
  25. package/catalog/agents/pr-summarizer/examples/sample-pr-summary.md +46 -0
  26. package/catalog/agents/pr-summarizer/examples/weak-vs-strong-summary.md +68 -0
  27. package/catalog/agents/pr-summarizer/references/identifying-risk.md +68 -0
  28. package/catalog/agents/pr-summarizer/references/reading-the-diff.md +68 -0
  29. package/catalog/agents/pr-summarizer/references/test-plan-and-missing-tests.md +64 -0
  30. package/catalog/agents/pr-summarizer/references/writing-the-summary.md +63 -0
  31. package/catalog/agents/pr-summarizer/scripts/diff-risk.mjs +111 -0
  32. package/catalog/agents/refactoring-specialist/AGENT.md +185 -0
  33. package/catalog/agents/refactoring-specialist/examples/before-after.md +91 -0
  34. package/catalog/agents/refactoring-specialist/examples/refactor-plan.md +97 -0
  35. package/catalog/agents/refactoring-specialist/references/large-scale-refactor.md +50 -0
  36. package/catalog/agents/refactoring-specialist/references/safe-workflow.md +75 -0
  37. package/catalog/agents/refactoring-specialist/references/smell-catalog.md +76 -0
  38. package/catalog/agents/refactoring-specialist/scripts/detect-smells.mjs +150 -0
  39. package/catalog/agents/security-auditor/AGENT.md +168 -0
  40. package/catalog/agents/security-auditor/examples/audit-report.md +68 -0
  41. package/catalog/agents/security-auditor/examples/finding-template.md +31 -0
  42. package/catalog/agents/security-auditor/references/audit-workflow.md +116 -0
  43. package/catalog/agents/security-auditor/references/severity-and-reporting.md +56 -0
  44. package/catalog/agents/security-auditor/references/vuln-classes.md +129 -0
  45. package/catalog/agents/security-auditor/scripts/scan-secrets.mjs +86 -0
  46. package/catalog/agents/technical-writer/AGENT.md +163 -0
  47. package/catalog/agents/technical-writer/examples/how-to-example.md +76 -0
  48. package/catalog/agents/technical-writer/examples/reference-example.md +75 -0
  49. package/catalog/agents/technical-writer/references/clarity-and-style.md +52 -0
  50. package/catalog/agents/technical-writer/references/diataxis-and-doc-types.md +61 -0
  51. package/catalog/agents/technical-writer/references/structure-and-maintenance.md +59 -0
  52. package/catalog/agents/technical-writer/scripts/readability.mjs +103 -0
  53. package/catalog/agents/test-author/AGENT.md +177 -0
  54. package/catalog/agents/test-author/examples/test-plan.md +54 -0
  55. package/catalog/agents/test-author/examples/unit-test-example.ts +55 -0
  56. package/catalog/agents/test-author/references/aaa-and-naming.md +75 -0
  57. package/catalog/agents/test-author/references/mocking-and-fixtures.md +94 -0
  58. package/catalog/agents/test-author/references/test-types-and-pyramid.md +60 -0
  59. package/catalog/agents/test-author/scripts/check-coverage.mjs +145 -0
  60. package/catalog/agents/threat-modeler/AGENT.md +163 -0
  61. package/catalog/agents/threat-modeler/examples/dfd-example.md +55 -0
  62. package/catalog/agents/threat-modeler/examples/threat-model.md +81 -0
  63. package/catalog/agents/threat-modeler/references/dfd-and-trust-boundaries.md +76 -0
  64. package/catalog/agents/threat-modeler/references/mitigation-catalog.md +77 -0
  65. package/catalog/agents/threat-modeler/references/stride-method.md +68 -0
  66. package/catalog/agents/threat-modeler/scripts/stride-checklist.mjs +183 -0
  67. package/catalog/agents/vuln-scanner/AGENT.md +146 -0
  68. package/catalog/agents/vuln-scanner/examples/finding-template.md +57 -0
  69. package/catalog/agents/vuln-scanner/examples/scan-report.md +49 -0
  70. package/catalog/agents/vuln-scanner/references/remediation-and-severity.md +68 -0
  71. package/catalog/agents/vuln-scanner/references/scan-types-and-tools.md +83 -0
  72. package/catalog/agents/vuln-scanner/references/triage-and-false-positives.md +73 -0
  73. package/catalog/agents/vuln-scanner/scripts/parse-scan-results.mjs +133 -0
  74. package/catalog/packs/code-review-pack/PACK.md +100 -0
  75. package/catalog/packs/code-review-pack/examples/pr-flow-example.md +50 -0
  76. package/catalog/packs/code-review-pack/references/rollout-guide.md +40 -0
  77. package/catalog/packs/security-pack/PACK.md +128 -0
  78. package/catalog/packs/security-pack/examples/owasp-vuln-triage-and-fix.md +66 -0
  79. package/catalog/packs/security-pack/examples/threat-model-then-audit.md +77 -0
  80. package/catalog/packs/security-pack/references/choosing-the-right-tool.md +37 -0
  81. package/catalog/packs/security-pack/references/threat-model-to-remediation.md +69 -0
  82. package/catalog/packs/security-pack/references/workflow.md +56 -0
  83. package/catalog/skills/api-pagination/SKILL.md +83 -0
  84. package/catalog/skills/api-pagination/examples/keyset-queries.sql +38 -0
  85. package/catalog/skills/api-pagination/examples/response-shapes.md +51 -0
  86. package/catalog/skills/api-pagination/references/consuming-pages.md +39 -0
  87. package/catalog/skills/api-pagination/references/counting-and-totals.md +41 -0
  88. package/catalog/skills/api-pagination/references/cursor-encoding.md +34 -0
  89. package/catalog/skills/api-pagination/scripts/check-cursor.mjs +51 -0
  90. package/catalog/skills/caching-strategies/SKILL.md +180 -0
  91. package/catalog/skills/caching-strategies/examples/http-cache-headers.md +82 -0
  92. package/catalog/skills/caching-strategies/examples/redis-cache-aside.js +110 -0
  93. package/catalog/skills/caching-strategies/references/cache-patterns.md +93 -0
  94. package/catalog/skills/caching-strategies/references/eviction-and-ttl.md +67 -0
  95. package/catalog/skills/caching-strategies/references/invalidation-and-stampede.md +99 -0
  96. package/catalog/skills/caching-strategies/scripts/ttl-jitter.mjs +99 -0
  97. package/catalog/skills/conventional-commits/SKILL.md +135 -0
  98. package/catalog/skills/conventional-commits/examples/commit-examples.md +60 -0
  99. package/catalog/skills/conventional-commits/examples/commitlint.config.js +31 -0
  100. package/catalog/skills/conventional-commits/references/breaking-changes-semver.md +50 -0
  101. package/catalog/skills/conventional-commits/references/scoping-commits.md +42 -0
  102. package/catalog/skills/conventional-commits/references/spec.md +78 -0
  103. package/catalog/skills/conventional-commits/scripts/lint-commit.mjs +97 -0
  104. package/catalog/skills/database-migrations/SKILL.md +137 -0
  105. package/catalog/skills/database-migrations/examples/add-column-safe.sql +34 -0
  106. package/catalog/skills/database-migrations/examples/migration-config.example.json +27 -0
  107. package/catalog/skills/database-migrations/references/expand-contract.md +74 -0
  108. package/catalog/skills/database-migrations/references/rollback-and-safety.md +71 -0
  109. package/catalog/skills/database-migrations/references/zero-downtime-changes.md +84 -0
  110. package/catalog/skills/database-migrations/scripts/check-migration-reversible.mjs +139 -0
  111. package/catalog/skills/error-handling-patterns/SKILL.md +136 -0
  112. package/catalog/skills/error-handling-patterns/examples/express-error-middleware.js +93 -0
  113. package/catalog/skills/error-handling-patterns/examples/result-pattern.ts +81 -0
  114. package/catalog/skills/error-handling-patterns/references/error-taxonomy.md +91 -0
  115. package/catalog/skills/error-handling-patterns/references/language-patterns.md +102 -0
  116. package/catalog/skills/error-handling-patterns/references/retry-and-backoff.md +76 -0
  117. package/catalog/skills/error-handling-patterns/scripts/lint-empty-catch.mjs +113 -0
  118. package/catalog/skills/git-collaboration-workflows/SKILL.md +104 -0
  119. package/catalog/skills/git-collaboration-workflows/examples/branch-protection.md +48 -0
  120. package/catalog/skills/git-collaboration-workflows/examples/pr-review-playbook.md +48 -0
  121. package/catalog/skills/git-collaboration-workflows/references/branching-models.md +52 -0
  122. package/catalog/skills/git-collaboration-workflows/references/history-hygiene.md +44 -0
  123. package/catalog/skills/git-collaboration-workflows/scripts/check-branch-hygiene.mjs +62 -0
  124. package/catalog/skills/owasp-top10/SKILL.md +112 -0
  125. package/catalog/skills/owasp-top10/examples/sql-injection-fix.md +33 -0
  126. package/catalog/skills/owasp-top10/examples/xss-fix.md +27 -0
  127. package/catalog/skills/owasp-top10/references/access-control.md +36 -0
  128. package/catalog/skills/owasp-top10/references/crypto-failures.md +29 -0
  129. package/catalog/skills/owasp-top10/references/injection.md +39 -0
  130. package/catalog/skills/owasp-top10/references/ssrf-and-design.md +35 -0
  131. package/catalog/skills/owasp-top10/scripts/scan-injection.mjs +73 -0
  132. package/catalog/skills/prompt-engineering/SKILL.md +100 -0
  133. package/catalog/skills/prompt-engineering/examples/classification-prompt.md +29 -0
  134. package/catalog/skills/prompt-engineering/examples/extraction-prompt.md +25 -0
  135. package/catalog/skills/prompt-engineering/references/prompt-injection.md +34 -0
  136. package/catalog/skills/prompt-engineering/references/structured-output.md +34 -0
  137. package/catalog/skills/prompt-engineering/references/techniques.md +33 -0
  138. package/catalog/skills/prompt-engineering/scripts/validate-output.mjs +71 -0
  139. package/catalog/skills/readme-writing/SKILL.md +176 -0
  140. package/catalog/skills/readme-writing/examples/README.template.md +73 -0
  141. package/catalog/skills/readme-writing/examples/good-readme-example.md +95 -0
  142. package/catalog/skills/readme-writing/references/anatomy.md +107 -0
  143. package/catalog/skills/readme-writing/references/maintenance.md +68 -0
  144. package/catalog/skills/readme-writing/references/writing-style.md +79 -0
  145. package/catalog/skills/readme-writing/scripts/lint-readme.mjs +117 -0
  146. package/catalog/skills/refactoring-patterns/SKILL.md +178 -0
  147. package/catalog/skills/refactoring-patterns/examples/extract-function.before-after.js +57 -0
  148. package/catalog/skills/refactoring-patterns/examples/replace-conditional-with-polymorphism.before-after.ts +63 -0
  149. package/catalog/skills/refactoring-patterns/references/code-smells.md +92 -0
  150. package/catalog/skills/refactoring-patterns/references/refactoring-catalog.md +78 -0
  151. package/catalog/skills/refactoring-patterns/references/safe-workflow.md +74 -0
  152. package/catalog/skills/refactoring-patterns/scripts/detect-smells.mjs +137 -0
  153. package/catalog/skills/rest-api-design/SKILL.md +147 -0
  154. package/catalog/skills/rest-api-design/examples/error-envelope.json +26 -0
  155. package/catalog/skills/rest-api-design/examples/orders-api.openapi.yaml +106 -0
  156. package/catalog/skills/rest-api-design/references/error-handling.md +43 -0
  157. package/catalog/skills/rest-api-design/references/pagination.md +41 -0
  158. package/catalog/skills/rest-api-design/references/status-codes.md +32 -0
  159. package/catalog/skills/rest-api-design/references/versioning.md +31 -0
  160. package/catalog/skills/rest-api-design/scripts/check-envelope.mjs +62 -0
  161. package/catalog/skills/secrets-management/SKILL.md +134 -0
  162. package/catalog/skills/secrets-management/examples/env-example.md +41 -0
  163. package/catalog/skills/secrets-management/examples/rotation-runbook.md +50 -0
  164. package/catalog/skills/secrets-management/references/leak-response.md +47 -0
  165. package/catalog/skills/secrets-management/references/rotation.md +46 -0
  166. package/catalog/skills/secrets-management/references/secret-managers.md +52 -0
  167. package/catalog/skills/secrets-management/scripts/detect-hardcoded.mjs +96 -0
  168. package/catalog/skills/secure-auth/SKILL.md +135 -0
  169. package/catalog/skills/secure-auth/examples/auth-flow.md +60 -0
  170. package/catalog/skills/secure-auth/examples/jwt-verify.ts +89 -0
  171. package/catalog/skills/secure-auth/references/auth-attacks.md +76 -0
  172. package/catalog/skills/secure-auth/references/oauth2-oidc.md +65 -0
  173. package/catalog/skills/secure-auth/references/password-hashing.md +70 -0
  174. package/catalog/skills/secure-auth/references/sessions-vs-jwt.md +69 -0
  175. package/catalog/skills/secure-auth/scripts/check-password-policy.mjs +114 -0
  176. package/catalog/skills/sql-index-tuning/SKILL.md +171 -0
  177. package/catalog/skills/sql-index-tuning/examples/explain-walkthrough.sql +91 -0
  178. package/catalog/skills/sql-index-tuning/examples/index-ddl.sql +67 -0
  179. package/catalog/skills/sql-index-tuning/references/btree-internals.md +58 -0
  180. package/catalog/skills/sql-index-tuning/references/composite-and-covering.md +60 -0
  181. package/catalog/skills/sql-index-tuning/references/reading-explain.md +54 -0
  182. package/catalog/skills/sql-index-tuning/references/selectivity-and-cardinality.md +62 -0
  183. package/catalog/skills/sql-index-tuning/scripts/suggest-index.mjs +213 -0
  184. package/catalog/skills/test-plan-design/SKILL.md +154 -0
  185. package/catalog/skills/test-plan-design/examples/test-case-template.md +45 -0
  186. package/catalog/skills/test-plan-design/examples/test-plan.md +57 -0
  187. package/catalog/skills/test-plan-design/references/case-design.md +79 -0
  188. package/catalog/skills/test-plan-design/references/risk-prioritization.md +58 -0
  189. package/catalog/skills/test-plan-design/references/test-pyramid.md +58 -0
  190. package/catalog/skills/test-plan-design/scripts/coverage-gaps.mjs +109 -0
  191. package/free-tier.json +15 -0
  192. package/package.json +15 -4
  193. package/premium-index.json +1 -0
  194. package/src/config.js +31 -1
  195. package/src/license.js +143 -0
@@ -0,0 +1,68 @@
1
+ # The STRIDE Method
2
+
3
+ STRIDE is a threat-classification model created at Microsoft. Each letter names a category of threat
4
+ defined by the security property it violates. Walking every element of a system against all six
5
+ categories gives you systematic coverage instead of relying on whatever attacks you happen to think of.
6
+
7
+ ## The six categories
8
+
9
+ | Category | Property violated | The attacker's goal | Example |
10
+ |---|---|---|---|
11
+ | **Spoofing** | Authentication | Pretend to be someone/something else | Forged JWT, stolen session, impersonated service identity |
12
+ | **Tampering** | Integrity | Modify data or code | Altered request body, poisoned cache, modified DB row |
13
+ | **Repudiation** | Non-repudiation | Deny having done something | No audit trail for a refund; logs are editable |
14
+ | **Information disclosure** | Confidentiality | Read data they shouldn't | PII in logs, verbose errors, IDOR exposing other users' records |
15
+ | **Denial of service** | Availability | Make the system unavailable | Connection flood, expensive query amplification, lock exhaustion |
16
+ | **Elevation of privilege** | Authorization | Gain rights they shouldn't have | Missing server-side authz check, path traversal, sandbox escape |
17
+
18
+ ## Element-type → applicable categories
19
+
20
+ Not every category applies to every element type. Use this mapping so you don't waste effort (and don't
21
+ miss the relevant ones):
22
+
23
+ | Element type | S | T | R | I | D | E |
24
+ |---|:-:|:-:|:-:|:-:|:-:|:-:|
25
+ | External entity (user, third party) | ● | | ● | | | |
26
+ | Process (service, function) | ● | ● | ● | ● | ● | ● |
27
+ | Data store (DB, cache, queue, files) | | ● | ● | ● | ● | |
28
+ | Data flow (network call, IPC) | | ● | | ● | ● | |
29
+
30
+ A *process* is the most exposed element — all six categories apply. A *data store* can't be "spoofed"
31
+ (it has no identity to forge) but can be tampered with, leak data, be DoS'd, and may need to defend
32
+ against repudiation if it holds audit records.
33
+
34
+ ## Per-element question checklist
35
+
36
+ For each element on the diagram, ask the questions for its applicable categories:
37
+
38
+ **Spoofing**
39
+ - How is this entity/process authenticated? Can the credential be stolen, replayed, or forged?
40
+ - Is mutual authentication needed for service-to-service calls?
41
+
42
+ **Tampering**
43
+ - Can a request, message, or stored record be modified in transit or at rest?
44
+ - Is integrity protected (TLS, signatures, HMAC, checksums)?
45
+
46
+ **Repudiation**
47
+ - Is there a tamper-evident audit log of security-relevant actions?
48
+ - Can a user or admin alter or delete the evidence of their own actions?
49
+
50
+ **Information disclosure**
51
+ - What sensitive data does this element hold or transmit? Who can read it?
52
+ - Do errors, logs, headers, or timing leak information? Is data encrypted at rest and in transit?
53
+
54
+ **Denial of service**
55
+ - What resource (CPU, memory, connections, locks, quota) can an attacker exhaust?
56
+ - Are there rate limits, timeouts, quotas, and back-pressure?
57
+
58
+ **Elevation of privilege**
59
+ - Is every action authorized server-side, checking *ownership* not just authentication (IDOR)?
60
+ - Can input cross a trust boundary into a more privileged context (injection, deserialization, traversal)?
61
+
62
+ ## How STRIDE relates to DREAD and risk rating
63
+
64
+ STRIDE *finds and classifies* threats; it does not rate them. Pair it with a rating scheme — this package
65
+ uses a lightweight Likelihood × Impact score (see `AGENT.md` → Risk rating). DREAD (Damage,
66
+ Reproducibility, Exploitability, Affected users, Discoverability) is an alternative; it is more granular
67
+ but harder to apply consistently. For most design-time models, Likelihood × Impact is enough and more
68
+ repeatable across reviewers.
@@ -0,0 +1,183 @@
1
+ #!/usr/bin/env node
2
+ // Runnable check: validates that a threat-model document covers all six STRIDE
3
+ // categories for every element it names. Accepts either JSON or a markdown
4
+ // threat table, so you can lint a model before review.
5
+ //
6
+ // STRIDE = Spoofing, Tampering, Repudiation, Information disclosure,
7
+ // Denial of service, Elevation of privilege.
8
+ //
9
+ // Usage:
10
+ // node stride-checklist.mjs model.json # check a JSON model file
11
+ // node stride-checklist.mjs model.md # check a markdown threat table
12
+ // cat model.md | node stride-checklist.mjs # check from stdin
13
+ // node stride-checklist.mjs --selftest # run built-in test cases
14
+ //
15
+ // JSON shape (either accepted):
16
+ // { "elements": [ { "name": "Auth", "categories": ["S","T","R","I","D","E"] } ] }
17
+ // [ { "name": "Auth", "categories": ["Spoofing", "Tampering", ...] } ]
18
+ //
19
+ // Markdown: any table with an "Element" column and a "STRIDE" column; rows are
20
+ // grouped by element and the STRIDE cells are unioned per element.
21
+
22
+ import { readFileSync } from 'node:fs';
23
+
24
+ const STRIDE = ['S', 'T', 'R', 'I', 'D', 'E'];
25
+ const STRIDE_NAME = {
26
+ S: 'Spoofing', T: 'Tampering', R: 'Repudiation',
27
+ I: 'Information disclosure', D: 'Denial of service', E: 'Elevation of privilege',
28
+ };
29
+
30
+ // Normalize a category token (letter or full word) to a single STRIDE letter, or null.
31
+ export function toLetter(token) {
32
+ if (typeof token !== 'string') return null;
33
+ const t = token.trim().toUpperCase();
34
+ if (STRIDE.includes(t)) return t;
35
+ const word = token.trim().toLowerCase();
36
+ if (word.startsWith('spoof')) return 'S';
37
+ if (word.startsWith('tamper')) return 'T';
38
+ if (word.startsWith('repudiat')) return 'R';
39
+ if (word.startsWith('info')) return 'I';
40
+ if (word.startsWith('denial') || word === 'dos') return 'D';
41
+ if (word.startsWith('elevat') || word.includes('privilege')) return 'E';
42
+ return null;
43
+ }
44
+
45
+ // Build a map of element name -> Set of covered STRIDE letters.
46
+ function buildCoverage(elements) {
47
+ const map = new Map();
48
+ for (const el of elements) {
49
+ const name = (el && el.name ? String(el.name) : '').trim();
50
+ if (!name) continue;
51
+ if (!map.has(name)) map.set(name, new Set());
52
+ const set = map.get(name);
53
+ for (const c of el.categories || []) {
54
+ const letter = toLetter(c);
55
+ if (letter) set.add(letter);
56
+ }
57
+ }
58
+ return map;
59
+ }
60
+
61
+ // Parse a JSON threat model into an elements array.
62
+ function parseJson(text) {
63
+ const obj = JSON.parse(text);
64
+ const arr = Array.isArray(obj) ? obj : obj.elements;
65
+ if (!Array.isArray(arr)) throw new Error('expected an array or { elements: [...] }');
66
+ return arr;
67
+ }
68
+
69
+ // Parse a markdown threat table into an elements array.
70
+ function parseMarkdown(text) {
71
+ const lines = text.split('\n').filter((l) => l.trim().startsWith('|'));
72
+ if (lines.length < 2) throw new Error('no markdown table found');
73
+ const cells = (line) => line.split('|').slice(1, -1).map((c) => c.trim());
74
+ const header = cells(lines[0]).map((h) => h.toLowerCase());
75
+ const elIdx = header.findIndex((h) => h.includes('element'));
76
+ const strideIdx = header.findIndex((h) => h.includes('stride') || h === 'category');
77
+ if (elIdx === -1 || strideIdx === -1) {
78
+ throw new Error('table needs an "Element" column and a "STRIDE" column');
79
+ }
80
+ const out = [];
81
+ for (const line of lines.slice(1)) {
82
+ const row = cells(line);
83
+ if (row.every((c) => /^[-:]*$/.test(c))) continue; // separator row
84
+ if (row.length <= Math.max(elIdx, strideIdx)) continue;
85
+ out.push({ name: row[elIdx], categories: [row[strideIdx]] });
86
+ }
87
+ return out;
88
+ }
89
+
90
+ function parse(text) {
91
+ const trimmed = text.trim();
92
+ if (trimmed.startsWith('{') || trimmed.startsWith('[')) return parseJson(trimmed);
93
+ return parseMarkdown(trimmed);
94
+ }
95
+
96
+ // Returns { ok, elements: [{ name, missing: [letters] }] }
97
+ export function checkCoverage(elements) {
98
+ const coverage = buildCoverage(elements);
99
+ const report = [];
100
+ for (const [name, covered] of coverage) {
101
+ const missing = STRIDE.filter((c) => !covered.has(c));
102
+ report.push({ name, missing });
103
+ }
104
+ const ok = report.length > 0 && report.every((r) => r.missing.length === 0);
105
+ return { ok, elements: report };
106
+ }
107
+
108
+ function render(label, result) {
109
+ if (result.elements.length === 0) {
110
+ console.error(`✗ ${label}: no elements found in document`);
111
+ return;
112
+ }
113
+ for (const { name, missing } of result.elements) {
114
+ if (missing.length === 0) {
115
+ console.log(`✓ ${name}: all six STRIDE categories covered`);
116
+ } else {
117
+ const names = missing.map((m) => `${m} (${STRIDE_NAME[m]})`).join(', ');
118
+ console.error(`✗ ${name}: missing ${names}`);
119
+ }
120
+ }
121
+ console.log(result.ok ? `✓ ${label}: complete` : `✗ ${label}: incomplete`);
122
+ }
123
+
124
+ function checkText(label, text) {
125
+ let elements;
126
+ try { elements = parse(text); }
127
+ catch (e) { console.error(`✗ ${label}: ${e.message}`); return false; }
128
+ const result = checkCoverage(elements);
129
+ render(label, result);
130
+ return result.ok;
131
+ }
132
+
133
+ function selftest() {
134
+ const all = ['S', 'T', 'R', 'I', 'D', 'E'];
135
+ const complete = { elements: [
136
+ { name: 'Auth Service', categories: all },
137
+ { name: 'Order API', categories: ['Spoofing', 'Tampering', 'Repudiation',
138
+ 'Information disclosure', 'Denial of service', 'Elevation of privilege'] },
139
+ ] };
140
+ const incomplete = { elements: [
141
+ { name: 'Auth Service', categories: ['S', 'T', 'R', 'I', 'D', 'E'] },
142
+ { name: 'Order API', categories: ['S', 'T'] }, // missing R, I, D, E
143
+ ] };
144
+ const completeMd = [
145
+ '| ID | Element | STRIDE | Threat |',
146
+ '|----|-------------|--------|--------|',
147
+ '| T1 | Auth | S | spoof |',
148
+ '| T2 | Auth | T | tamper |',
149
+ '| T3 | Auth | R | repud |',
150
+ '| T4 | Auth | I | leak |',
151
+ '| T5 | Auth | D | flood |',
152
+ '| T6 | Auth | E | escal |',
153
+ ].join('\n');
154
+
155
+ const cases = [
156
+ ['complete_json', complete, true],
157
+ ['incomplete_json', incomplete, false],
158
+ ['complete_markdown', completeMd, true],
159
+ ];
160
+ let allExpected = true;
161
+ for (const [name, input, shouldPass] of cases) {
162
+ const elements = typeof input === 'string' ? parseMarkdown(input) : input.elements;
163
+ const { ok } = checkCoverage(elements);
164
+ const correct = ok === shouldPass;
165
+ allExpected &&= correct;
166
+ console.log(`${correct ? '✓' : '✗'} selftest ${name}: ${ok ? 'complete' : 'incomplete'} (expected ${shouldPass ? 'complete' : 'incomplete'})`);
167
+ }
168
+ process.exit(allExpected ? 0 : 1);
169
+ }
170
+
171
+ const arg = process.argv[2];
172
+ if (arg === '--selftest') {
173
+ selftest();
174
+ } else if (arg) {
175
+ let text;
176
+ try { text = readFileSync(arg, 'utf8'); }
177
+ catch (e) { console.error(`✗ cannot read ${arg}: ${e.message}`); process.exit(1); }
178
+ process.exit(checkText(arg, text) ? 0 : 1);
179
+ } else {
180
+ let buf = '';
181
+ process.stdin.on('data', (c) => (buf += c));
182
+ process.stdin.on('end', () => process.exit(checkText('stdin', buf) ? 0 : 1));
183
+ }
@@ -0,0 +1,146 @@
1
+ ---
2
+ name: vuln-scanner
3
+ description: Use when scanning a project's dependencies, source, config, and container images for known vulnerabilities (CVEs), risky versions, and exposed secrets — then triaging findings and proposing safe, prioritized remediations. Invoke before releases, on dependency bumps, or for periodic supply-chain hygiene.
4
+ tools: Read, Grep, Glob, Bash
5
+ model: claude-haiku-4-5
6
+ type: agent
7
+ version: 2.0.0
8
+ updated: 2026-06-29
9
+ ---
10
+ # Vulnerability Scanner
11
+
12
+ You are an application-security scanning agent. Your job is to keep the software supply chain clean:
13
+ known-bad dependencies, leaked secrets, and risky configuration are caught and **triaged** before they
14
+ ship. A scan that dumps 400 raw findings is not security work — it is noise. Your value is in turning
15
+ raw scanner output into a short, ranked, actionable list a developer can act on today.
16
+
17
+ You operate read-only by default. You read lockfiles, source, and config; you run scanners in
18
+ report-only mode; you never auto-apply upgrades or rewrite history without explicit instruction. You
19
+ propose changes — a human approves them.
20
+
21
+ ## Role and mindset
22
+
23
+ - **Signal over volume.** The deliverable is a triaged report, not a tool dump. Every finding you
24
+ surface must carry a severity, an exploitability judgment, and a concrete next step.
25
+ - **Reachability matters.** A critical CVE in a code path the app never calls is lower real-world risk
26
+ than a medium CVE on an internet-facing entrypoint. Say so.
27
+ - **Fix-forward.** Each vulnerable dependency gets a fix version and a breaking-vs-non-breaking label,
28
+ so the reader knows whether it's a one-line bump or a migration.
29
+ - **Secrets are incidents.** A committed secret is assumed compromised. Removal is not remediation;
30
+ rotation is.
31
+
32
+ ## Scan workflow
33
+
34
+ Work through these phases in order. Skipping triage (phase 5) is the most common failure — do not.
35
+
36
+ 1. **Scope and inventory.** Identify the stack(s) from manifests and lockfiles. Map direct vs.
37
+ transitive dependencies. Note what is in scope (app code, deps, containers, IaC) and what is not.
38
+ 2. **Dependency / SCA scan.** Resolve installed versions from lockfiles and match against known CVEs.
39
+ Flag outdated, unmaintained (no release in a long window), or vulnerable-pinned packages.
40
+ 3. **Secret scan.** Search the working tree (and, when asked, history) for high-entropy strings, known
41
+ key formats, tokens, and connection strings. Distinguish live secrets from test fixtures and
42
+ placeholders.
43
+ 4. **Config / SAST / container scan.** Check risky config defaults (debug on, permissive CORS, disabled
44
+ TLS verification), obvious source-level sinks, and base-image CVEs when a Dockerfile is present.
45
+ 5. **Triage.** Deduplicate, suppress confirmed false positives with a recorded reason, assess
46
+ reachability/exploitability, and assign a final severity. This is where raw output becomes a report.
47
+ 6. **Prioritize and report.** Group into *fix now* (critical/high, reachable, non-breaking), *plan*
48
+ (breaking upgrades, lower severity), and *accept/monitor* (with justification).
49
+ 7. **Self-check.** Before returning, verify the output against the self-check list below.
50
+
51
+ The heavy detail for each scan family lives in [scan-types-and-tools](references/scan-types-and-tools.md);
52
+ the triage rules live in [triage-and-false-positives](references/triage-and-false-positives.md).
53
+
54
+ ## Triage rules
55
+
56
+ Triage is the core skill. A finding moves from *raw* to *reported* only after you answer four questions:
57
+
58
+ ```text
59
+ 1. Is it real? -> dedupe + drop confirmed false positives (record why)
60
+ 2. Is it reachable? -> is the vulnerable function/path actually used or exposed?
61
+ 3. How bad if hit? -> impact: RCE / auth bypass / data exposure / DoS / info leak
62
+ 4. How easy to fix? -> non-breaking bump | breaking upgrade | config change | rotate
63
+ ```
64
+
65
+ Use a normalized severity scale (`critical > high > medium > low > info`). When a scanner's CVSS
66
+ disagrees with reachability, state both: e.g. *"CVSS 9.8 critical, but the vulnerable parser is never
67
+ invoked — downgraded to medium, scheduled not blocking."* Make the reasoning explicit so a reviewer can
68
+ overrule it.
69
+
70
+ You can normalize and sort a batch of raw findings deterministically with the bundled script:
71
+
72
+ ```bash
73
+ # Dedupe + sort a JSON array of raw findings by triaged severity
74
+ node scripts/parse-scan-results.mjs findings.json
75
+ # Verify the script's own triage ordering/counts
76
+ node scripts/parse-scan-results.mjs --selftest # exits 0 on success
77
+ ```
78
+
79
+ ## Output format
80
+
81
+ Return a single report in this structure (see [examples/scan-report.md](examples/scan-report.md) for a
82
+ full worked example and [examples/finding-template.md](examples/finding-template.md) for one finding):
83
+
84
+ 1. **Summary** — counts by severity, scan scope, and the single most urgent action.
85
+ 2. **Fix now** — reachable critical/high with fix version + breaking flag.
86
+ 3. **Plan** — breaking upgrades and lower-severity items, grouped.
87
+ 4. **Exposed secrets** — each with a rotation instruction, not just "remove it."
88
+ 5. **Config / container risks** — misconfigurations and base-image CVEs.
89
+ 6. **Accepted / suppressed** — false positives and risk-accepted items, each with a reason.
90
+
91
+ Every dependency finding states: package, current version, fix version, severity, breaking? (yes/no),
92
+ and reachability note. Keep prose tight; the reader is a busy developer.
93
+
94
+ ## Common pitfalls and failure modes
95
+
96
+ Security scanning fails in predictable ways. Guard against each:
97
+
98
+ - **False positives reported as real.** Scanners flag vendored test fixtures, example keys, and
99
+ unreachable code. Verify before you alarm. A report full of bogus findings trains the team to ignore
100
+ you — see [triage-and-false-positives](references/triage-and-false-positives.md).
101
+ - **Alert fatigue.** Surfacing every low/info finding buries the one critical that matters. Rank
102
+ hard; push noise into an appendix or "accept/monitor" bucket.
103
+ - **Scanning without triage.** Pasting raw `npm audit` / Trivy output is not a deliverable. Untriaged
104
+ output has near-zero signal. Always run phase 5.
105
+ - **CVSS worship.** Treating the headline CVSS as final risk ignores reachability and context. A 9.8 in
106
+ dead code is not your top priority.
107
+ - **"Removed the secret" theater.** Deleting a key from the latest commit leaves it in history and,
108
+ more importantly, still valid at the provider. Always rotate.
109
+ - **Auto-upgrading across majors.** A blind `^` bump that crosses a major can break the build worse
110
+ than the CVE. Flag migration risk; never silently jump majors.
111
+ - **Version-only matching.** Some advisories only apply with a specific feature flag or platform. Note
112
+ the qualifier rather than flagging every pinned version.
113
+
114
+ ## When NOT to use / boundaries
115
+
116
+ - **Not a penetration test.** This agent does static/dependency/secret analysis. It does not run live
117
+ exploits, fuzz endpoints, or perform authenticated DAST against a deployed target.
118
+ - **Not a remediation bot.** It proposes prioritized fixes; it does not auto-bump versions, rewrite git
119
+ history, or rotate credentials. A human executes those.
120
+ - **Not a compliance auditor.** It won't produce SOC 2 / ISO evidence packages or policy attestations.
121
+ - **Not a code reviewer.** For design-level security (authz logic, crypto choices, threat surface),
122
+ hand off rather than overreach.
123
+ - **No network calls implied.** Treat advisory data as the snapshot available at scan time; flag when a
124
+ fresh advisory-DB pull is needed for confidence.
125
+
126
+ ## Self-check (run before returning)
127
+
128
+ - [ ] Every finding has a severity, reachability note, and concrete next step.
129
+ - [ ] Each vulnerable dependency states a fix version and breaking? flag.
130
+ - [ ] Every secret has a rotation instruction, not just removal.
131
+ - [ ] False positives are suppressed with a recorded reason, not silently dropped.
132
+ - [ ] Findings are ranked; the top item is genuinely the most urgent.
133
+ - [ ] No major-version upgrade is recommended without a migration-risk note.
134
+
135
+ ## Files in this package
136
+
137
+ - `AGENT.md` — this system prompt (role, workflow, triage, output, boundaries).
138
+ - `references/scan-types-and-tools.md` — SAST, DAST, SCA, secret, and container scanning families.
139
+ - `references/triage-and-false-positives.md` — dedup, reachability, and false-positive handling.
140
+ - `references/remediation-and-severity.md` — severity scale, fix strategy, and rotation playbook.
141
+ - `examples/scan-report.md` — a complete worked triaged report.
142
+ - `examples/finding-template.md` — the canonical shape of a single finding.
143
+ - `scripts/parse-scan-results.mjs` — normalizes, dedupes, and severity-sorts raw findings; `--selftest`.
144
+
145
+ Pairs with the `security-auditor` agent, the `threat-modeler` agent, the `secrets-management` skill, and
146
+ the `owasp-top10` skill.
@@ -0,0 +1,57 @@
1
+ # Finding Template
2
+
3
+ The canonical shape of a single triaged finding. Every finding the agent reports should carry these
4
+ fields so the reader never has to ask "is it real?", "does it matter here?", or "what do I do?".
5
+
6
+ ## Fields
7
+
8
+ | Field | Required | Description |
9
+ |---|---|---|
10
+ | `id` | yes | Advisory ID (CVE/GHSA) or a stable local id for non-CVE findings |
11
+ | `title` | yes | One-line human summary |
12
+ | `type` | yes | `dependency` \| `secret` \| `config` \| `sast` \| `container` |
13
+ | `package` / `location` | yes | Affected package@version, or file:line |
14
+ | `severity` | yes | Final triaged severity: `critical`/`high`/`medium`/`low`/`info` |
15
+ | `cvss` | when known | Raw scanner score, shown alongside the adjusted severity |
16
+ | `reachability` | yes | `reachable` \| `unreachable` \| `dev-only` \| `unknown` + one-line reason |
17
+ | `fix` | yes | Concrete remediation (fix version, rotate, config change) |
18
+ | `breaking` | deps only | `yes` / `no` — semver/changelog judgment |
19
+ | `bucket` | yes | `fix-now` \| `plan` \| `accept-monitor` |
20
+ | `notes` | optional | Triage reasoning, especially any severity adjustment |
21
+
22
+ ## Worked example (dependency)
23
+
24
+ ```json
25
+ {
26
+ "id": "CVE-2020-8203",
27
+ "title": "Prototype pollution in lodash",
28
+ "type": "dependency",
29
+ "package": "lodash@4.17.15",
30
+ "severity": "high",
31
+ "cvss": 7.4,
32
+ "reachability": "reachable — called from util/merge.js with request data",
33
+ "fix": "upgrade to lodash@4.17.21",
34
+ "breaking": "no",
35
+ "bucket": "fix-now",
36
+ "notes": "Direct dependency; minimal patch bump clears the advisory."
37
+ }
38
+ ```
39
+
40
+ ## Worked example (secret)
41
+
42
+ ```json
43
+ {
44
+ "id": "SECRET-001",
45
+ "title": "AWS access key committed to repo",
46
+ "type": "secret",
47
+ "location": "config/legacy.env:4",
48
+ "severity": "critical",
49
+ "reachability": "reachable — live credential in shared history",
50
+ "fix": "rotate in IAM (revoke old key), replace with AWS_ACCESS_KEY_ID env var, add pre-commit hook",
51
+ "bucket": "fix-now",
52
+ "notes": "Assume compromised. Removal from latest commit is NOT sufficient — rotation required."
53
+ }
54
+ ```
55
+
56
+ This is also the schema `scripts/parse-scan-results.mjs` normalizes toward (it keys on `id` + `package`
57
+ for dedup and sorts by `severity`).
@@ -0,0 +1,49 @@
1
+ # Example: Vulnerability Scan Report
2
+
3
+ A worked example of the report shape this agent produces. Note the structure: a tight summary, a short
4
+ *fix now* list, then everything else ranked below it. The raw scan had 47 findings; triage reduced the
5
+ release-blocking set to 3.
6
+
7
+ ---
8
+
9
+ ## Summary
10
+
11
+ - **Scope:** npm dependencies (lockfile), source secret scan, Dockerfile base image.
12
+ - **Findings:** 1 critical, 2 high, 6 medium, 38 low/info (47 raw -> 9 actionable after triage).
13
+ - **Most urgent:** rotate the AWS key committed in `config/legacy.env` — assume compromised.
14
+
15
+ ## Fix now (release-blocking)
16
+
17
+ | Item | Severity | Fix | Breaking? | Reachability |
18
+ |---|---|---|---|---|
19
+ | AWS access key in `config/legacy.env` | critical | rotate in IAM, move to env var | n/a | Live credential, public history |
20
+ | `lodash@4.17.15` (CVE-2020-8203) | high | -> `4.17.21` | no | Reachable via `util/merge.js` |
21
+ | `axios@0.21.0` (SSRF, CVE-2021-3749) | high | -> `0.21.4` | no | Used in outbound webhook client |
22
+
23
+ ## Plan (schedule, not blocking)
24
+
25
+ - **`next@12 -> 14` (3 medium CVEs):** breaking major. Clears 3 advisories but requires app-router
26
+ migration review. Estimate: 1 sprint. Group as one coordinated upgrade.
27
+ - **`debug=true` in `config/prod.json`:** medium. Leaks stack traces to clients; set `false`.
28
+ - **6 transitive medium CVEs in dev-only deps:** real but build-time only; bump opportunistically.
29
+
30
+ ## Exposed secrets
31
+
32
+ | Secret | Location | Action |
33
+ |---|---|---|
34
+ | AWS access key `AKIA…` | `config/legacy.env:4` | **Rotate** in IAM (revoke old), replace with `AWS_ACCESS_KEY_ID` env var, add pre-commit secret hook |
35
+ | Slack webhook URL | `scripts/notify.sh:12` | Rotate webhook in Slack, move to secret manager |
36
+
37
+ Removal from the latest commit is **not** sufficient — both are still valid at the provider.
38
+
39
+ ## Config / container risks
40
+
41
+ - **Base image `node:18.0-alpine`:** carries 4 OS-package CVEs. Bump to current `node:18-alpine` patch.
42
+ - **Container runs as root:** add a non-root `USER` to the Dockerfile.
43
+
44
+ ## Accepted / suppressed (with reason)
45
+
46
+ - **CVE-2025-XXXX in `fast-xml@3.1.0` (CVSS 9.8):** vulnerable `parseAttrs` path requires
47
+ `allowAttributes:true`; app uses defaults. Downgraded critical -> medium, scheduled.
48
+ - **`AKIAEXAMPLE…` in `docs/setup.md`:** documentation placeholder, not a live key. Suppressed.
49
+ - **CVE in `jest@…`:** dev/test-only dependency, not in production bundle. Backlog.
@@ -0,0 +1,68 @@
1
+ # Remediation and Severity
2
+
3
+ Once a finding is triaged, the deliverable is a *fix the reader can act on*. This reference defines the
4
+ severity scale, the dependency-fix strategy, and the secret-rotation playbook.
5
+
6
+ ## Severity scale
7
+
8
+ Use a single normalized scale across all scan families so the report is comparable:
9
+
10
+ | Severity | Meaning | Default action |
11
+ |---|---|---|
12
+ | `critical` | Reachable RCE, auth bypass, or active secret leak | Block release; fix now |
13
+ | `high` | Serious impact, exploitable with moderate effort | Fix before release |
14
+ | `medium` | Real but constrained (limited reach or impact) | Schedule next sprint |
15
+ | `low` | Minor / hardening | Backlog |
16
+ | `info` | Awareness only | No action required |
17
+
18
+ Final severity = scanner severity **adjusted by reachability and impact** (see
19
+ [triage-and-false-positives](triage-and-false-positives.md)). Always show your adjustment reasoning.
20
+
21
+ ## Dependency remediation strategy
22
+
23
+ For every vulnerable dependency, state the fix version and whether it's breaking:
24
+
25
+ 1. **Prefer the minimal bump that clears the CVE.** If `1.2.3 -> 1.2.4` fixes it, recommend that, not
26
+ the latest 3.x.
27
+ 2. **Label breaking vs. non-breaking** by semver distance and changelog. Crossing a major is breaking
28
+ until proven otherwise.
29
+ 3. **Transitive deps:** if you don't own the dependency directly, fix via the parent bump, or a
30
+ lockfile override / resolution (`overrides` in npm, `resolutions` in yarn/pnpm) — and flag overrides
31
+ as a temporary measure, not a permanent pin.
32
+ 4. **Group breaking upgrades separately** under *plan* with a migration-risk note. Never bundle a risky
33
+ major bump into a "quick fix" list.
34
+ 5. **No fix available?** Document the mitigation (disable the feature, add input validation, network
35
+ isolation) and mark for monitoring.
36
+
37
+ ```text
38
+ Fix-now bucket -> non-breaking bumps that clear critical/high, reachable
39
+ Plan bucket -> breaking upgrades, lower-severity, or coordinated changes
40
+ Accept/monitor -> no fix yet, or risk-accepted with justification
41
+ ```
42
+
43
+ ## Secret remediation — rotation, not removal
44
+
45
+ A committed secret is compromised the moment it lands in a shared repo. The fix is always:
46
+
47
+ 1. **Rotate first.** Issue a new credential at the provider and revoke the old one. Until this is done,
48
+ the secret is live regardless of repo state.
49
+ 2. **Remove from code.** Replace with an env var or secret-manager reference.
50
+ 3. **Purge from history** if required (history rewrite or, more often, treat as exposed and rely on
51
+ rotation — rewriting shared history is disruptive and incomplete if the repo was cloned/forked).
52
+ 4. **Add prevention.** A pre-commit secret hook and a `.gitignore` entry so it doesn't recur.
53
+
54
+ > "Deleted the key in the latest commit" is **not** remediation. The credential is still valid at the
55
+ > provider and still present in every prior commit, clone, and CI cache.
56
+
57
+ ## Writing the remediation line
58
+
59
+ Each finding's recommendation should be copy-pasteable and unambiguous:
60
+
61
+ ```text
62
+ lodash 4.17.15 -> 4.17.21 | high | non-breaking | prototype-pollution CVE-2020-8203, reachable in util/merge.js
63
+ AWS key in config/old.env | critical | rotate | revoke in IAM, replace with env var, add pre-commit hook
64
+ debug=true in prod config | medium | config | set debug=false; leaks stack traces to clients
65
+ ```
66
+
67
+ Tie remediation effort to severity so the reader can plan: a *fix now* of ten non-breaking bumps is an
68
+ afternoon; one breaking major in *plan* may be a sprint. Make that tradeoff visible.
@@ -0,0 +1,83 @@
1
+ # Scan Types and Tools
2
+
3
+ Vulnerability scanning is not one activity — it is a family of complementary techniques, each with a
4
+ different blind spot. A credible scan combines several. Use this reference to pick the right family for
5
+ the target and to understand what each one *cannot* see.
6
+
7
+ ## SCA — Software Composition Analysis (dependency scanning)
8
+
9
+ Matches your resolved dependency versions against known-vulnerability databases (CVE/NVD, GitHub
10
+ Advisory, OSV).
11
+
12
+ - **Inputs:** lockfiles (`package-lock.json`, `pnpm-lock.yaml`, `poetry.lock`, `Cargo.lock`, `go.sum`).
13
+ Always read the **lockfile**, not the manifest range — `^1.2.0` tells you nothing about what shipped.
14
+ - **Strengths:** high-precision for *known* CVEs; cheap; covers transitive deps.
15
+ - **Blind spots:** zero-days, logic bugs, anything not yet in an advisory DB. Version-only matching can
16
+ over-report (advisory may need a specific feature flag).
17
+ - **Triage hook:** flag direct vs. transitive — a transitive CVE may be fixable only by bumping the
18
+ parent, or pinning via an override/resolution.
19
+
20
+ ```bash
21
+ # Inventory before judging — never trust the manifest range alone
22
+ node -e "const l=require('./package-lock.json');console.log(Object.keys(l.packages||{}).length,'resolved packages')"
23
+ ```
24
+
25
+ ## Secret scanning
26
+
27
+ Finds credentials committed to the repo: API keys, tokens, private keys, connection strings,
28
+ high-entropy blobs.
29
+
30
+ - **Inputs:** working tree by default; git history when explicitly requested.
31
+ - **Detection:** known-format regexes (e.g. `AKIA…` AWS keys, `ghp_…` GitHub tokens, `-----BEGIN ...
32
+ PRIVATE KEY-----`) plus entropy heuristics.
33
+ - **Blind spots:** secrets in untracked files, encrypted blobs, or rotated-but-still-referenced values.
34
+ - **Critical rule:** a found secret is assumed compromised. Removal ≠ remediation. See
35
+ [remediation-and-severity](remediation-and-severity.md) for the rotation playbook.
36
+
37
+ ```bash
38
+ # Cheap first pass for common key formats (illustrative — a real scan uses a tool)
39
+ grep -rERn 'AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{36}|-----BEGIN [A-Z ]*PRIVATE KEY-----' . \
40
+ --include='*.*' || echo "no obvious key-format matches"
41
+ ```
42
+
43
+ ## SAST — Static Application Security Testing
44
+
45
+ Analyzes source/AST for vulnerable patterns: injection sinks, unsafe deserialization, path traversal,
46
+ hardcoded crypto, tainted-data flows.
47
+
48
+ - **Strengths:** finds bugs in *your* code, not just dependencies; runs without deploying.
49
+ - **Blind spots:** high false-positive rate; struggles with dynamic dispatch and framework magic;
50
+ cannot judge runtime config.
51
+ - **Triage hook:** SAST output needs the heaviest false-positive filtering. Confirm the sink is
52
+ reachable with attacker-controlled input before alarming.
53
+
54
+ ## DAST — Dynamic Application Security Testing
55
+
56
+ Probes a *running* application from the outside: injection, auth handling, misconfigured headers, TLS.
57
+
58
+ - **Strengths:** finds runtime/config issues SAST can't see; low false positives for what it confirms.
59
+ - **Blind spots:** only covers exercised endpoints; needs a deployed target; can be destructive.
60
+ - **Boundary:** this agent does **not** perform live DAST/exploitation — that is a pen-test activity.
61
+ Note when DAST is warranted and hand off.
62
+
63
+ ## Container & IaC scanning
64
+
65
+ When a `Dockerfile`, image, or infra-as-code (Terraform, Kubernetes manifests) is present:
66
+
67
+ - **Base-image CVEs:** OS packages in the image carry their own advisories; a clean app on a stale base
68
+ image is still vulnerable.
69
+ - **Image hygiene:** running as root, secrets baked into layers, unpinned `latest` tags.
70
+ - **IaC misconfig:** public S3 buckets, `0.0.0.0/0` security groups, disabled encryption.
71
+
72
+ ## Choosing per target
73
+
74
+ | Target present | Run | Primary risk caught |
75
+ |---|---|---|
76
+ | Lockfile | SCA | Known CVEs in deps |
77
+ | Any source | Secret scan + SAST | Leaked creds, injection sinks |
78
+ | Dockerfile / image | Container scan | Base-image CVEs, root, baked secrets |
79
+ | Terraform / k8s | IaC scan | Public exposure, weak crypto config |
80
+ | Deployed URL | DAST (hand off) | Runtime/config exploits |
81
+
82
+ No single family is sufficient. Combine, then triage everything through
83
+ [triage-and-false-positives](triage-and-false-positives.md).