@panguard-ai/atr 1.4.2 → 1.5.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 (182) hide show
  1. package/dist/index.d.ts +4 -22
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -14
  4. package/dist/index.js.map +1 -1
  5. package/dist/quality.d.ts +8 -0
  6. package/dist/quality.d.ts.map +1 -0
  7. package/dist/quality.js +8 -0
  8. package/dist/quality.js.map +1 -0
  9. package/package.json +15 -49
  10. package/dist/cli.d.ts +0 -14
  11. package/dist/cli.d.ts.map +0 -1
  12. package/dist/cli.js +0 -744
  13. package/dist/cli.js.map +0 -1
  14. package/dist/coverage-analyzer.d.ts +0 -43
  15. package/dist/coverage-analyzer.d.ts.map +0 -1
  16. package/dist/coverage-analyzer.js +0 -329
  17. package/dist/coverage-analyzer.js.map +0 -1
  18. package/dist/engine.d.ts +0 -136
  19. package/dist/engine.d.ts.map +0 -1
  20. package/dist/engine.js +0 -781
  21. package/dist/engine.js.map +0 -1
  22. package/dist/loader.d.ts +0 -21
  23. package/dist/loader.d.ts.map +0 -1
  24. package/dist/loader.js +0 -149
  25. package/dist/loader.js.map +0 -1
  26. package/dist/mcp-server.d.ts +0 -13
  27. package/dist/mcp-server.d.ts.map +0 -1
  28. package/dist/mcp-server.js +0 -244
  29. package/dist/mcp-server.js.map +0 -1
  30. package/dist/mcp-tools/coverage-gaps.d.ts +0 -13
  31. package/dist/mcp-tools/coverage-gaps.d.ts.map +0 -1
  32. package/dist/mcp-tools/coverage-gaps.js +0 -57
  33. package/dist/mcp-tools/coverage-gaps.js.map +0 -1
  34. package/dist/mcp-tools/list-rules.d.ts +0 -17
  35. package/dist/mcp-tools/list-rules.d.ts.map +0 -1
  36. package/dist/mcp-tools/list-rules.js +0 -45
  37. package/dist/mcp-tools/list-rules.js.map +0 -1
  38. package/dist/mcp-tools/scan.d.ts +0 -18
  39. package/dist/mcp-tools/scan.d.ts.map +0 -1
  40. package/dist/mcp-tools/scan.js +0 -87
  41. package/dist/mcp-tools/scan.js.map +0 -1
  42. package/dist/mcp-tools/submit-proposal.d.ts +0 -12
  43. package/dist/mcp-tools/submit-proposal.d.ts.map +0 -1
  44. package/dist/mcp-tools/submit-proposal.js +0 -116
  45. package/dist/mcp-tools/submit-proposal.js.map +0 -1
  46. package/dist/mcp-tools/threat-summary.d.ts +0 -12
  47. package/dist/mcp-tools/threat-summary.d.ts.map +0 -1
  48. package/dist/mcp-tools/threat-summary.js +0 -72
  49. package/dist/mcp-tools/threat-summary.js.map +0 -1
  50. package/dist/mcp-tools/validate.d.ts +0 -15
  51. package/dist/mcp-tools/validate.d.ts.map +0 -1
  52. package/dist/mcp-tools/validate.js +0 -57
  53. package/dist/mcp-tools/validate.js.map +0 -1
  54. package/dist/modules/index.d.ts +0 -144
  55. package/dist/modules/index.d.ts.map +0 -1
  56. package/dist/modules/index.js +0 -82
  57. package/dist/modules/index.js.map +0 -1
  58. package/dist/modules/semantic.d.ts +0 -105
  59. package/dist/modules/semantic.d.ts.map +0 -1
  60. package/dist/modules/semantic.js +0 -289
  61. package/dist/modules/semantic.js.map +0 -1
  62. package/dist/modules/session.d.ts +0 -70
  63. package/dist/modules/session.d.ts.map +0 -1
  64. package/dist/modules/session.js +0 -163
  65. package/dist/modules/session.js.map +0 -1
  66. package/dist/rule-scaffolder.d.ts +0 -39
  67. package/dist/rule-scaffolder.d.ts.map +0 -1
  68. package/dist/rule-scaffolder.js +0 -171
  69. package/dist/rule-scaffolder.js.map +0 -1
  70. package/dist/session-tracker.d.ts +0 -56
  71. package/dist/session-tracker.d.ts.map +0 -1
  72. package/dist/session-tracker.js +0 -175
  73. package/dist/session-tracker.js.map +0 -1
  74. package/dist/skill-fingerprint.d.ts +0 -96
  75. package/dist/skill-fingerprint.d.ts.map +0 -1
  76. package/dist/skill-fingerprint.js +0 -336
  77. package/dist/skill-fingerprint.js.map +0 -1
  78. package/dist/types.d.ts +0 -211
  79. package/dist/types.d.ts.map +0 -1
  80. package/dist/types.js +0 -6
  81. package/dist/types.js.map +0 -1
  82. package/rules/agent-manipulation/ATR-2026-00030-cross-agent-attack.yaml +0 -177
  83. package/rules/agent-manipulation/ATR-2026-00032-goal-hijacking.yaml +0 -137
  84. package/rules/agent-manipulation/ATR-2026-00074-cross-agent-privilege-escalation.yaml +0 -117
  85. package/rules/agent-manipulation/ATR-2026-00076-inter-agent-message-spoofing.yaml +0 -167
  86. package/rules/agent-manipulation/ATR-2026-00077-human-trust-exploitation.yaml +0 -146
  87. package/rules/agent-manipulation/ATR-2026-00108-consensus-sybil-attack.yaml +0 -105
  88. package/rules/agent-manipulation/ATR-2026-00116-a2a-message-validation.yaml +0 -92
  89. package/rules/agent-manipulation/ATR-2026-00117-agent-identity-spoofing.yaml +0 -92
  90. package/rules/agent-manipulation/ATR-2026-00118-approval-fatigue.yaml +0 -89
  91. package/rules/agent-manipulation/ATR-2026-00119-social-engineering-via-agent.yaml +0 -89
  92. package/rules/agent-manipulation/ATR-2026-00132-casual-authority-escalation.yaml +0 -99
  93. package/rules/agent-manipulation/ATR-2026-00139-casual-authority-redirect.yaml +0 -53
  94. package/rules/context-exfiltration/ATR-2026-00020-system-prompt-leak.yaml +0 -177
  95. package/rules/context-exfiltration/ATR-2026-00021-api-key-exposure.yaml +0 -178
  96. package/rules/context-exfiltration/ATR-2026-00075-agent-memory-manipulation.yaml +0 -117
  97. package/rules/context-exfiltration/ATR-2026-00102-disguised-analytics-exfiltration.yaml +0 -71
  98. package/rules/context-exfiltration/ATR-2026-00113-credential-theft.yaml +0 -89
  99. package/rules/context-exfiltration/ATR-2026-00114-oauth-token-abuse.yaml +0 -89
  100. package/rules/context-exfiltration/ATR-2026-00115-env-var-harvesting.yaml +0 -90
  101. package/rules/context-exfiltration/ATR-2026-00136-tool-response-data-piggyback.yaml +0 -100
  102. package/rules/context-exfiltration/ATR-2026-00141-example-format-key-leak.yaml +0 -52
  103. package/rules/context-exfiltration/ATR-2026-00142-piggyback-transition-words.yaml +0 -55
  104. package/rules/context-exfiltration/ATR-2026-00145-obfuscated-key-disclosure.yaml +0 -49
  105. package/rules/context-exfiltration/ATR-2026-00146-env-var-existence-probe.yaml +0 -49
  106. package/rules/data-poisoning/ATR-2026-00070-data-poisoning.yaml +0 -162
  107. package/rules/excessive-autonomy/ATR-2026-00050-runaway-agent-loop.yaml +0 -136
  108. package/rules/excessive-autonomy/ATR-2026-00051-resource-exhaustion.yaml +0 -139
  109. package/rules/excessive-autonomy/ATR-2026-00052-cascading-failure.yaml +0 -155
  110. package/rules/excessive-autonomy/ATR-2026-00098-unauthorized-financial-action.yaml +0 -157
  111. package/rules/excessive-autonomy/ATR-2026-00099-high-risk-tool-gate.yaml +0 -176
  112. package/rules/model-security/ATR-2026-00072-model-behavior-extraction.yaml +0 -117
  113. package/rules/model-security/ATR-2026-00073-malicious-finetuning-data.yaml +0 -110
  114. package/rules/privilege-escalation/ATR-2026-00040-privilege-escalation.yaml +0 -177
  115. package/rules/privilege-escalation/ATR-2026-00041-scope-creep.yaml +0 -126
  116. package/rules/privilege-escalation/ATR-2026-00107-delayed-execution-bypass.yaml +0 -69
  117. package/rules/privilege-escalation/ATR-2026-00110-eval-injection.yaml +0 -92
  118. package/rules/privilege-escalation/ATR-2026-00111-shell-escape.yaml +0 -93
  119. package/rules/privilege-escalation/ATR-2026-00112-dynamic-import-exploitation.yaml +0 -89
  120. package/rules/privilege-escalation/ATR-2026-00143-casual-privilege-escalation.yaml +0 -53
  121. package/rules/privilege-escalation/ATR-2026-00144-rationalized-safety-bypass.yaml +0 -49
  122. package/rules/prompt-injection/ATR-2026-00001-direct-prompt-injection.yaml +0 -563
  123. package/rules/prompt-injection/ATR-2026-00002-indirect-prompt-injection.yaml +0 -216
  124. package/rules/prompt-injection/ATR-2026-00003-jailbreak-attempt.yaml +0 -397
  125. package/rules/prompt-injection/ATR-2026-00004-system-prompt-override.yaml +0 -308
  126. package/rules/prompt-injection/ATR-2026-00005-multi-turn-injection.yaml +0 -183
  127. package/rules/prompt-injection/ATR-2026-00080-encoding-evasion.yaml +0 -88
  128. package/rules/prompt-injection/ATR-2026-00081-semantic-multi-turn.yaml +0 -85
  129. package/rules/prompt-injection/ATR-2026-00082-fingerprint-evasion.yaml +0 -84
  130. package/rules/prompt-injection/ATR-2026-00083-indirect-tool-injection.yaml +0 -87
  131. package/rules/prompt-injection/ATR-2026-00084-structured-data-injection.yaml +0 -86
  132. package/rules/prompt-injection/ATR-2026-00085-audit-evasion.yaml +0 -84
  133. package/rules/prompt-injection/ATR-2026-00086-visual-spoofing.yaml +0 -88
  134. package/rules/prompt-injection/ATR-2026-00087-rule-probing.yaml +0 -82
  135. package/rules/prompt-injection/ATR-2026-00088-adaptive-countermeasure.yaml +0 -84
  136. package/rules/prompt-injection/ATR-2026-00089-polymorphic-skill.yaml +0 -85
  137. package/rules/prompt-injection/ATR-2026-00090-threat-intel-exfil.yaml +0 -84
  138. package/rules/prompt-injection/ATR-2026-00091-nested-payload.yaml +0 -88
  139. package/rules/prompt-injection/ATR-2026-00092-consensus-poisoning.yaml +0 -92
  140. package/rules/prompt-injection/ATR-2026-00093-gradual-escalation.yaml +0 -86
  141. package/rules/prompt-injection/ATR-2026-00094-audit-bypass.yaml +0 -86
  142. package/rules/prompt-injection/ATR-2026-00097-cjk-injection-patterns.yaml +0 -339
  143. package/rules/prompt-injection/ATR-2026-00104-persona-hijacking.yaml +0 -74
  144. package/rules/prompt-injection/ATR-2026-00130-indirect-authority-claim.yaml +0 -97
  145. package/rules/prompt-injection/ATR-2026-00131-fictional-academic-framing.yaml +0 -93
  146. package/rules/prompt-injection/ATR-2026-00133-paraphrase-injection.yaml +0 -111
  147. package/rules/prompt-injection/ATR-2026-00137-authority-claim-injection.yaml +0 -52
  148. package/rules/prompt-injection/ATR-2026-00138-fictional-framing-bypass.yaml +0 -51
  149. package/rules/prompt-injection/ATR-2026-00140-indirect-reference-reversal.yaml +0 -52
  150. package/rules/prompt-injection/ATR-2026-00148-language-switch-injection.yaml +0 -71
  151. package/rules/skill-compromise/ATR-2026-00060-skill-impersonation.yaml +0 -155
  152. package/rules/skill-compromise/ATR-2026-00061-description-behavior-mismatch.yaml +0 -100
  153. package/rules/skill-compromise/ATR-2026-00062-hidden-capability.yaml +0 -98
  154. package/rules/skill-compromise/ATR-2026-00063-skill-chain-attack.yaml +0 -99
  155. package/rules/skill-compromise/ATR-2026-00064-over-permissioned-skill.yaml +0 -117
  156. package/rules/skill-compromise/ATR-2026-00065-skill-update-attack.yaml +0 -95
  157. package/rules/skill-compromise/ATR-2026-00066-parameter-injection.yaml +0 -108
  158. package/rules/skill-compromise/ATR-2026-00120-skill-instruction-injection.yaml +0 -121
  159. package/rules/skill-compromise/ATR-2026-00121-skill-dangerous-script.yaml +0 -165
  160. package/rules/skill-compromise/ATR-2026-00122-skill-weaponized-instruction.yaml +0 -114
  161. package/rules/skill-compromise/ATR-2026-00123-skill-overreach-permissions.yaml +0 -118
  162. package/rules/skill-compromise/ATR-2026-00124-skill-name-squatting.yaml +0 -98
  163. package/rules/skill-compromise/ATR-2026-00125-context-poisoning-compaction.yaml +0 -93
  164. package/rules/skill-compromise/ATR-2026-00126-skill-rug-pull-setup.yaml +0 -99
  165. package/rules/skill-compromise/ATR-2026-00127-subcommand-overflow.yaml +0 -74
  166. package/rules/skill-compromise/ATR-2026-00128-html-comment-hidden-payload.yaml +0 -79
  167. package/rules/skill-compromise/ATR-2026-00129-unicode-smuggling.yaml +0 -73
  168. package/rules/skill-compromise/ATR-2026-00134-fork-claim-impersonation.yaml +0 -86
  169. package/rules/skill-compromise/ATR-2026-00135-exfil-url-in-instructions.yaml +0 -82
  170. package/rules/skill-compromise/ATR-2026-00147-fork-impersonation.yaml +0 -48
  171. package/rules/tool-poisoning/ATR-2026-00010-mcp-malicious-response.yaml +0 -239
  172. package/rules/tool-poisoning/ATR-2026-00011-tool-output-injection.yaml +0 -196
  173. package/rules/tool-poisoning/ATR-2026-00012-unauthorized-tool-call.yaml +0 -201
  174. package/rules/tool-poisoning/ATR-2026-00013-tool-ssrf.yaml +0 -219
  175. package/rules/tool-poisoning/ATR-2026-00095-supply-chain-poisoning.yaml +0 -93
  176. package/rules/tool-poisoning/ATR-2026-00096-registry-poisoning.yaml +0 -95
  177. package/rules/tool-poisoning/ATR-2026-00100-consent-bypass-instruction.yaml +0 -82
  178. package/rules/tool-poisoning/ATR-2026-00101-trust-escalation-override.yaml +0 -68
  179. package/rules/tool-poisoning/ATR-2026-00103-hidden-safety-bypass-instruction.yaml +0 -73
  180. package/rules/tool-poisoning/ATR-2026-00105-silent-action-concealment.yaml +0 -69
  181. package/rules/tool-poisoning/ATR-2026-00106-schema-description-contradiction.yaml +0 -68
  182. package/spec/atr-schema.yaml +0 -404
@@ -1,96 +0,0 @@
1
- /**
2
- * Skill Behavioral Fingerprint
3
- * Skill 行為指紋追蹤器
4
- *
5
- * Tracks what each skill "normally does" across invocations, then detects
6
- * behavioral drift when a previously-trusted skill starts acting differently.
7
- *
8
- * Solves the "installed then turns malicious" scenario:
9
- * - First N invocations: build fingerprint (what APIs, what patterns, what scope)
10
- * - After fingerprint stabilizes: flag any deviation as anomaly
11
- *
12
- * 追蹤每個 skill 的「正常行為」,然後在行為偏移時偵測:
13
- * - 前 N 次呼叫:建立指紋
14
- * - 指紋穩定後:任何偏離都標記為異常
15
- *
16
- * @module agent-threat-rules/skill-fingerprint
17
- */
18
- import type { AgentEvent } from './types.js';
19
- /** Behavioral capabilities observed for a skill */
20
- interface SkillCapabilities {
21
- /** Seen filesystem operations (read/write/delete) */
22
- readonly filesystemOps: ReadonlySet<string>;
23
- /** Seen network destinations (hostnames) */
24
- readonly networkTargets: ReadonlySet<string>;
25
- /** Seen environment variable accesses */
26
- readonly envAccesses: ReadonlySet<string>;
27
- /** Seen child process executions */
28
- readonly processExecs: ReadonlySet<string>;
29
- /** Seen output patterns (categories: data, error, redirect, exfiltration) */
30
- readonly outputPatterns: ReadonlySet<string>;
31
- }
32
- /** Immutable fingerprint snapshot */
33
- export interface SkillFingerprint {
34
- readonly skillName: string;
35
- readonly invocationCount: number;
36
- readonly firstSeen: number;
37
- readonly lastSeen: number;
38
- readonly isStable: boolean;
39
- readonly capabilities: SkillCapabilities;
40
- /** Hash of capabilities for quick comparison */
41
- readonly capabilityHash: string;
42
- }
43
- /** Anomaly when behavior deviates from fingerprint */
44
- export interface BehaviorAnomaly {
45
- readonly skillName: string;
46
- readonly anomalyType: 'new_filesystem_op' | 'new_network_target' | 'new_env_access' | 'new_process_exec' | 'new_output_pattern' | 'capability_expansion';
47
- readonly description: string;
48
- readonly severity: 'low' | 'medium' | 'high' | 'critical';
49
- readonly newValue: string;
50
- readonly timestamp: number;
51
- }
52
- export interface SkillFingerprintConfig {
53
- /** Minimum invocations before fingerprint can stabilize (default: 10) */
54
- stabilityThreshold?: number;
55
- /** Consecutive clean invocations to mark stable (default: 5) */
56
- stableStreak?: number;
57
- }
58
- export declare class SkillFingerprintStore {
59
- private readonly fingerprints;
60
- private readonly stabilityThreshold;
61
- private readonly stableStreak;
62
- constructor(config?: SkillFingerprintConfig);
63
- /**
64
- * Record a skill invocation and detect behavioral anomalies.
65
- * Returns anomalies if the fingerprint was stable and new capabilities appeared.
66
- *
67
- * 記錄 skill 呼叫並偵測行為異常。
68
- * 如果指紋已穩定且出現新能力,回傳異常列表。
69
- */
70
- recordInvocation(skillName: string, event: AgentEvent): readonly BehaviorAnomaly[];
71
- /**
72
- * Get an immutable fingerprint snapshot for a skill.
73
- * 取得某 skill 的不可變指紋快照。
74
- */
75
- getFingerprint(skillName: string): SkillFingerprint | undefined;
76
- /** Get all tracked skill names */
77
- getTrackedSkills(): string[];
78
- /** Get count of stable fingerprints */
79
- getStableCount(): number;
80
- /** Get total tracked skills */
81
- getTrackedCount(): number;
82
- /**
83
- * Reset a skill's fingerprint (e.g., after a legitimate update).
84
- * 重置 skill 指紋(例如合法更新後)。
85
- */
86
- resetFingerprint(skillName: string): void;
87
- /**
88
- * Evict fingerprints not seen since cutoffMs ago.
89
- * 清除超過 cutoffMs 未活動的指紋。
90
- */
91
- cleanup(cutoffMs: number): number;
92
- private getOrCreate;
93
- private computeCapabilityHash;
94
- }
95
- export {};
96
- //# sourceMappingURL=skill-fingerprint.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skill-fingerprint.d.ts","sourceRoot":"","sources":["../src/skill-fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7C,mDAAmD;AACnD,UAAU,iBAAiB;IACzB,qDAAqD;IACrD,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5C,4CAA4C;IAC5C,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7C,yCAAyC;IACzC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C,oCAAoC;IACpC,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,6EAA6E;IAC7E,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IACzC,gDAAgD;IAChD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAChB,mBAAmB,GACnB,oBAAoB,GACpB,gBAAgB,GAChB,kBAAkB,GAClB,oBAAoB,GACpB,sBAAsB,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAC1D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AA0GD,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyC;IACtE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,MAAM,CAAC,EAAE,sBAAsB;IAK3C;;;;;;OAMG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,eAAe,EAAE;IA0IlF;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAqB/D,kCAAkC;IAClC,gBAAgB,IAAI,MAAM,EAAE;IAI5B,uCAAuC;IACvC,cAAc,IAAI,MAAM;IAQxB,+BAA+B;IAC/B,eAAe,IAAI,MAAM;IAIzB;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIzC;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAgBjC,OAAO,CAAC,WAAW;IAkCnB,OAAO,CAAC,qBAAqB;CAU9B"}
@@ -1,336 +0,0 @@
1
- /**
2
- * Skill Behavioral Fingerprint
3
- * Skill 行為指紋追蹤器
4
- *
5
- * Tracks what each skill "normally does" across invocations, then detects
6
- * behavioral drift when a previously-trusted skill starts acting differently.
7
- *
8
- * Solves the "installed then turns malicious" scenario:
9
- * - First N invocations: build fingerprint (what APIs, what patterns, what scope)
10
- * - After fingerprint stabilizes: flag any deviation as anomaly
11
- *
12
- * 追蹤每個 skill 的「正常行為」,然後在行為偏移時偵測:
13
- * - 前 N 次呼叫:建立指紋
14
- * - 指紋穩定後:任何偏離都標記為異常
15
- *
16
- * @module agent-threat-rules/skill-fingerprint
17
- */
18
- import { createHash } from 'node:crypto';
19
- // ---------------------------------------------------------------------------
20
- // Pattern detectors (regex-based, no LLM needed)
21
- // ---------------------------------------------------------------------------
22
- const FS_WRITE_PATTERN = /(?:write(?:File)?|appendFile|fs\.write|truncate|mkdir|rmdir|unlink|rm\s+-)/i;
23
- const FS_READ_PATTERN = /(?:read(?:File)?|readdir|stat|access|exists|glob|find\s)/i;
24
- const FS_DELETE_PATTERN = /(?:unlink|rm\s+-rf|delete(?:File)?|removeDir|rmdir)/i;
25
- const NETWORK_PATTERN = /(?:https?:\/\/|fetch|curl|wget|axios|http\.request|net\.connect|socket)[\s('"]*([a-zA-Z0-9.-]+(?:\.[a-zA-Z]{2,}))/i;
26
- const ENV_PATTERN = /(?:process\.env|os\.environ|getenv|System\.getenv)\[?['"(]?([A-Z_][A-Z0-9_]*)/i;
27
- const ENV_INLINE_PATTERN = /\$\{?([A-Z_][A-Z0-9_]{2,})\}?/g;
28
- const EXEC_PATTERN = /(?:child_process|spawn|exec(?:File)?|system\(|popen|subprocess|shell_exec|os\.system)\s*\(\s*['"(]?([^\s'")\]]{1,80})/i;
29
- const EXFIL_PATTERN = /(?:base64|btoa|encode|compress|deflate|gzip).*(?:http|fetch|curl|send|post|upload)/i;
30
- const REDIRECT_PATTERN = /(?:redirect|forward|proxy|tunnel)\s+(?:to\s+)?(?:https?:\/\/)/i;
31
- /** Classify a text content into behavioral capabilities */
32
- function extractCapabilities(text) {
33
- const result = {
34
- filesystemOps: [],
35
- networkTargets: [],
36
- envAccesses: [],
37
- processExecs: [],
38
- outputPatterns: [],
39
- };
40
- if (!text || text.length === 0)
41
- return result;
42
- // Limit analysis to first 10KB to prevent ReDoS
43
- const safeText = text.slice(0, 10_240);
44
- // Filesystem
45
- if (FS_WRITE_PATTERN.test(safeText))
46
- result.filesystemOps.push('write');
47
- if (FS_READ_PATTERN.test(safeText))
48
- result.filesystemOps.push('read');
49
- if (FS_DELETE_PATTERN.test(safeText))
50
- result.filesystemOps.push('delete');
51
- // Network targets
52
- const netMatch = safeText.match(NETWORK_PATTERN);
53
- if (netMatch?.[1])
54
- result.networkTargets.push(netMatch[1]);
55
- // Environment variable accesses
56
- const envMatch = safeText.match(ENV_PATTERN);
57
- if (envMatch?.[1])
58
- result.envAccesses.push(envMatch[1]);
59
- // Also check inline env vars like $HOME, ${API_KEY}
60
- for (const m of safeText.matchAll(ENV_INLINE_PATTERN)) {
61
- if (m[1] && !result.envAccesses.includes(m[1])) {
62
- result.envAccesses.push(m[1]);
63
- }
64
- }
65
- // Process executions
66
- const execMatch = safeText.match(EXEC_PATTERN);
67
- if (execMatch?.[1])
68
- result.processExecs.push(execMatch[1]);
69
- // Output patterns
70
- if (EXFIL_PATTERN.test(safeText))
71
- result.outputPatterns.push('exfiltration');
72
- if (REDIRECT_PATTERN.test(safeText))
73
- result.outputPatterns.push('redirect');
74
- return result;
75
- }
76
- // ---------------------------------------------------------------------------
77
- // Fingerprint Store
78
- // ---------------------------------------------------------------------------
79
- /** Default invocations needed before fingerprint is considered stable */
80
- const DEFAULT_STABILITY_THRESHOLD = 10;
81
- /** Consecutive invocations with no new capabilities to mark stable */
82
- const DEFAULT_STABLE_STREAK = 5;
83
- /** Maximum number of skills to track */
84
- const MAX_SKILLS = 5_000;
85
- export class SkillFingerprintStore {
86
- fingerprints = new Map();
87
- stabilityThreshold;
88
- stableStreak;
89
- constructor(config) {
90
- this.stabilityThreshold = config?.stabilityThreshold ?? DEFAULT_STABILITY_THRESHOLD;
91
- this.stableStreak = config?.stableStreak ?? DEFAULT_STABLE_STREAK;
92
- }
93
- /**
94
- * Record a skill invocation and detect behavioral anomalies.
95
- * Returns anomalies if the fingerprint was stable and new capabilities appeared.
96
- *
97
- * 記錄 skill 呼叫並偵測行為異常。
98
- * 如果指紋已穩定且出現新能力,回傳異常列表。
99
- */
100
- recordInvocation(skillName, event) {
101
- const now = Date.now();
102
- const fp = this.getOrCreate(skillName, now);
103
- fp.invocationCount++;
104
- fp.lastSeen = now;
105
- // Extract capabilities from event content + fields
106
- const content = [
107
- event.content ?? '',
108
- event.fields?.['tool_args'] ?? '',
109
- event.fields?.['tool_response'] ?? '',
110
- ].join('\n');
111
- const caps = extractCapabilities(content);
112
- // Check for anomalies (only if fingerprint is stable)
113
- const anomalies = [];
114
- const isStable = fp.stableHash !== null;
115
- if (isStable) {
116
- // Detect NEW capabilities not in the stable fingerprint
117
- for (const op of caps.filesystemOps) {
118
- if (!fp.filesystemOps.has(op)) {
119
- anomalies.push({
120
- skillName,
121
- anomalyType: 'new_filesystem_op',
122
- description: `Skill "${skillName}" performing new filesystem operation: ${op} (not in baseline)`,
123
- severity: op === 'delete' ? 'critical' : op === 'write' ? 'high' : 'medium',
124
- newValue: op,
125
- timestamp: now,
126
- });
127
- }
128
- }
129
- for (const target of caps.networkTargets) {
130
- if (!fp.networkTargets.has(target)) {
131
- anomalies.push({
132
- skillName,
133
- anomalyType: 'new_network_target',
134
- description: `Skill "${skillName}" contacting new network target: ${target}`,
135
- severity: 'high',
136
- newValue: target,
137
- timestamp: now,
138
- });
139
- }
140
- }
141
- for (const env of caps.envAccesses) {
142
- if (!fp.envAccesses.has(env)) {
143
- const isSensitive = /(?:KEY|SECRET|TOKEN|PASSWORD|CREDENTIAL)/i.test(env);
144
- anomalies.push({
145
- skillName,
146
- anomalyType: 'new_env_access',
147
- description: `Skill "${skillName}" accessing new env var: ${env}`,
148
- severity: isSensitive ? 'critical' : 'medium',
149
- newValue: env,
150
- timestamp: now,
151
- });
152
- }
153
- }
154
- for (const proc of caps.processExecs) {
155
- if (!fp.processExecs.has(proc)) {
156
- anomalies.push({
157
- skillName,
158
- anomalyType: 'new_process_exec',
159
- description: `Skill "${skillName}" executing new process: ${proc}`,
160
- severity: 'critical',
161
- newValue: proc,
162
- timestamp: now,
163
- });
164
- }
165
- }
166
- for (const pat of caps.outputPatterns) {
167
- if (!fp.outputPatterns.has(pat)) {
168
- anomalies.push({
169
- skillName,
170
- anomalyType: 'new_output_pattern',
171
- description: `Skill "${skillName}" exhibiting new pattern: ${pat}`,
172
- severity: pat === 'exfiltration' ? 'critical' : 'high',
173
- newValue: pat,
174
- timestamp: now,
175
- });
176
- }
177
- }
178
- }
179
- // Update fingerprint with observed capabilities
180
- let newCapsSeen = false;
181
- for (const op of caps.filesystemOps) {
182
- if (!fp.filesystemOps.has(op)) {
183
- fp.filesystemOps.add(op);
184
- newCapsSeen = true;
185
- }
186
- }
187
- for (const t of caps.networkTargets) {
188
- if (!fp.networkTargets.has(t)) {
189
- fp.networkTargets.add(t);
190
- newCapsSeen = true;
191
- }
192
- }
193
- for (const e of caps.envAccesses) {
194
- if (!fp.envAccesses.has(e)) {
195
- fp.envAccesses.add(e);
196
- newCapsSeen = true;
197
- }
198
- }
199
- for (const p of caps.processExecs) {
200
- if (!fp.processExecs.has(p)) {
201
- fp.processExecs.add(p);
202
- newCapsSeen = true;
203
- }
204
- }
205
- for (const o of caps.outputPatterns) {
206
- if (!fp.outputPatterns.has(o)) {
207
- fp.outputPatterns.add(o);
208
- newCapsSeen = true;
209
- }
210
- }
211
- // Track stability
212
- if (!isStable) {
213
- if (newCapsSeen) {
214
- fp.stableStreak = 0;
215
- }
216
- else {
217
- fp.stableStreak++;
218
- }
219
- // Mark stable when threshold met
220
- if (fp.invocationCount >= this.stabilityThreshold && fp.stableStreak >= this.stableStreak) {
221
- fp.stableHash = this.computeCapabilityHash(fp);
222
- }
223
- }
224
- return anomalies;
225
- }
226
- /**
227
- * Get an immutable fingerprint snapshot for a skill.
228
- * 取得某 skill 的不可變指紋快照。
229
- */
230
- getFingerprint(skillName) {
231
- const fp = this.fingerprints.get(skillName);
232
- if (!fp)
233
- return undefined;
234
- return {
235
- skillName: fp.skillName,
236
- invocationCount: fp.invocationCount,
237
- firstSeen: fp.firstSeen,
238
- lastSeen: fp.lastSeen,
239
- isStable: fp.stableHash !== null,
240
- capabilities: {
241
- filesystemOps: new Set(fp.filesystemOps),
242
- networkTargets: new Set(fp.networkTargets),
243
- envAccesses: new Set(fp.envAccesses),
244
- processExecs: new Set(fp.processExecs),
245
- outputPatterns: new Set(fp.outputPatterns),
246
- },
247
- capabilityHash: fp.stableHash ?? this.computeCapabilityHash(fp),
248
- };
249
- }
250
- /** Get all tracked skill names */
251
- getTrackedSkills() {
252
- return [...this.fingerprints.keys()];
253
- }
254
- /** Get count of stable fingerprints */
255
- getStableCount() {
256
- let count = 0;
257
- for (const fp of this.fingerprints.values()) {
258
- if (fp.stableHash !== null)
259
- count++;
260
- }
261
- return count;
262
- }
263
- /** Get total tracked skills */
264
- getTrackedCount() {
265
- return this.fingerprints.size;
266
- }
267
- /**
268
- * Reset a skill's fingerprint (e.g., after a legitimate update).
269
- * 重置 skill 指紋(例如合法更新後)。
270
- */
271
- resetFingerprint(skillName) {
272
- this.fingerprints.delete(skillName);
273
- }
274
- /**
275
- * Evict fingerprints not seen since cutoffMs ago.
276
- * 清除超過 cutoffMs 未活動的指紋。
277
- */
278
- cleanup(cutoffMs) {
279
- const cutoff = Date.now() - cutoffMs;
280
- let evicted = 0;
281
- for (const [name, fp] of this.fingerprints) {
282
- if (fp.lastSeen < cutoff) {
283
- this.fingerprints.delete(name);
284
- evicted++;
285
- }
286
- }
287
- return evicted;
288
- }
289
- // -----------------------------------------------------------------------
290
- // Private
291
- // -----------------------------------------------------------------------
292
- getOrCreate(skillName, now) {
293
- const existing = this.fingerprints.get(skillName);
294
- if (existing)
295
- return existing;
296
- // Evict oldest if at capacity
297
- if (this.fingerprints.size >= MAX_SKILLS) {
298
- let oldestName;
299
- let oldestTime = Infinity;
300
- for (const [name, fp] of this.fingerprints) {
301
- if (fp.lastSeen < oldestTime) {
302
- oldestTime = fp.lastSeen;
303
- oldestName = name;
304
- }
305
- }
306
- if (oldestName)
307
- this.fingerprints.delete(oldestName);
308
- }
309
- const fp = {
310
- skillName,
311
- invocationCount: 0,
312
- firstSeen: now,
313
- lastSeen: now,
314
- filesystemOps: new Set(),
315
- networkTargets: new Set(),
316
- envAccesses: new Set(),
317
- processExecs: new Set(),
318
- outputPatterns: new Set(),
319
- stableHash: null,
320
- stableStreak: 0,
321
- };
322
- this.fingerprints.set(skillName, fp);
323
- return fp;
324
- }
325
- computeCapabilityHash(fp) {
326
- const parts = [
327
- [...fp.filesystemOps].sort().join(','),
328
- [...fp.networkTargets].sort().join(','),
329
- [...fp.envAccesses].sort().join(','),
330
- [...fp.processExecs].sort().join(','),
331
- [...fp.outputPatterns].sort().join(','),
332
- ];
333
- return createHash('sha256').update(parts.join('|')).digest('hex').slice(0, 16);
334
- }
335
- }
336
- //# sourceMappingURL=skill-fingerprint.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skill-fingerprint.js","sourceRoot":"","sources":["../src/skill-fingerprint.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts DELETED
@@ -1,211 +0,0 @@
1
- /**
2
- * ATR (Agent Threat Rules) type definitions
3
- * @module agent-threat-rules/types
4
- */
5
- export type ATRStatus = 'draft' | 'experimental' | 'stable' | 'deprecated';
6
- export type ATRSeverity = 'critical' | 'high' | 'medium' | 'low' | 'informational';
7
- export type ATRCategory = 'prompt-injection' | 'tool-poisoning' | 'context-exfiltration' | 'agent-manipulation' | 'privilege-escalation' | 'excessive-autonomy' | 'data-poisoning' | 'model-abuse' | 'skill-compromise';
8
- export type ATRConfidence = 'high' | 'medium' | 'low';
9
- export type ATRSourceType = 'llm_io' | 'tool_call' | 'mcp_exchange' | 'agent_behavior' | 'multi_agent_comm' | 'context_window' | 'memory_access' | 'skill_lifecycle' | 'skill_permission' | 'skill_chain';
10
- export type ATRMatchType = 'contains' | 'regex' | 'exact' | 'starts_with';
11
- export type ATROperator = 'gt' | 'lt' | 'eq' | 'gte' | 'lte' | 'deviation_from_baseline';
12
- export type ATRAction = 'block_input' | 'block_output' | 'block_tool' | 'quarantine_session' | 'reset_context' | 'alert' | 'snapshot' | 'escalate' | 'reduce_permissions' | 'kill_agent';
13
- export interface ATRReferences {
14
- owasp_llm?: string[];
15
- owasp_agentic?: string[];
16
- mitre_atlas?: string[];
17
- mitre_attack?: string[];
18
- cve?: string[];
19
- }
20
- export type ATRScanTarget = 'mcp' | 'skill' | 'both' | 'runtime';
21
- export interface ATRTags {
22
- category: ATRCategory;
23
- subcategory?: string;
24
- confidence?: ATRConfidence;
25
- scan_target?: ATRScanTarget;
26
- }
27
- export interface ATRAgentSource {
28
- type: ATRSourceType;
29
- framework?: string[];
30
- provider?: string[];
31
- }
32
- export interface ATRPatternCondition {
33
- field: string;
34
- patterns: string[];
35
- match_type: ATRMatchType;
36
- case_sensitive?: boolean;
37
- }
38
- export interface ATRBehavioralCondition {
39
- metric: string;
40
- operator: ATROperator;
41
- threshold: number;
42
- window?: string;
43
- }
44
- export interface ATRSequenceStep {
45
- field?: string;
46
- patterns?: string[];
47
- match_type?: ATRMatchType;
48
- metric?: string;
49
- operator?: ATROperator;
50
- threshold?: number;
51
- }
52
- export interface ATRSequenceCondition {
53
- ordered: boolean;
54
- within: string;
55
- steps: ATRSequenceStep[];
56
- }
57
- /** Array-format condition: {field, operator, value} used by most rules */
58
- export interface ATRArrayCondition {
59
- field: string;
60
- operator: string;
61
- value: string;
62
- description?: string;
63
- }
64
- /** Named-map conditions or array conditions */
65
- export type ATRConditions = ATRArrayCondition[] | Record<string, ATRPatternCondition | ATRBehavioralCondition | ATRSequenceCondition>;
66
- export interface ATRDetection {
67
- conditions: ATRConditions;
68
- /** "any" = OR across all conditions, "all" = AND. For named format: boolean expression string. */
69
- condition: string;
70
- false_positives?: string[];
71
- }
72
- export interface ATRResponse {
73
- actions: ATRAction[];
74
- auto_response_threshold?: string;
75
- message_template?: string;
76
- }
77
- export interface ATRTestCase {
78
- input?: string;
79
- tool_response?: string;
80
- agent_output?: string;
81
- tool_name?: string;
82
- tool_args?: string;
83
- expected: 'trigger' | 'no_trigger' | 'triggered' | 'not_triggered';
84
- }
85
- export interface ATRTestCases {
86
- true_positives: ATRTestCase[];
87
- true_negatives: ATRTestCase[];
88
- }
89
- export interface ATRRule {
90
- title: string;
91
- id: string;
92
- rule_version?: number;
93
- status: ATRStatus;
94
- description: string;
95
- author: string;
96
- date: string;
97
- modified?: string;
98
- schema_version?: string;
99
- detection_tier?: string;
100
- maturity?: string;
101
- severity: ATRSeverity;
102
- references?: ATRReferences;
103
- tags: ATRTags;
104
- agent_source: ATRAgentSource;
105
- detection: ATRDetection;
106
- response: ATRResponse;
107
- test_cases?: ATRTestCases;
108
- }
109
- /** Event types that the ATR engine can evaluate */
110
- export type AgentEventType = 'llm_input' | 'llm_output' | 'tool_call' | 'tool_response' | 'agent_behavior' | 'multi_agent_message' | 'mcp_exchange';
111
- /** An agent event to evaluate against ATR rules */
112
- export interface AgentEvent {
113
- type: AgentEventType;
114
- timestamp: string;
115
- /** The text content to analyze */
116
- content: string;
117
- /** Specific field values for pattern matching */
118
- fields?: Record<string, string>;
119
- /** Behavioral metrics for threshold-based detection */
120
- metrics?: Record<string, number>;
121
- /** Session identifier for correlation */
122
- sessionId?: string;
123
- /** Source agent identifier */
124
- agentId?: string;
125
- /** Additional metadata */
126
- metadata?: Record<string, unknown>;
127
- /** Scan context: when 'skill', all rules fire regardless of agent_source.type,
128
- * with cross-context confidence downweighting for MCP-only rules. */
129
- scanContext?: 'mcp' | 'skill';
130
- }
131
- export type ScanContextType = 'native' | 'cross-context';
132
- /** Result when an ATR rule matches an event */
133
- export interface ATRMatch {
134
- rule: ATRRule;
135
- matchedConditions: string[];
136
- matchedPatterns: string[];
137
- confidence: number;
138
- timestamp: string;
139
- /** Whether this match is native (rule designed for this scan path) or cross-context */
140
- scan_context: ScanContextType;
141
- }
142
- /** Verdict outcome from evaluating matched rules */
143
- export type VerdictOutcome = 'allow' | 'ask' | 'deny';
144
- /** Verdict returned after evaluating an event against all rules */
145
- export interface ATRVerdict {
146
- readonly outcome: VerdictOutcome;
147
- readonly reason: string;
148
- readonly matchCount: number;
149
- readonly highestSeverity: ATRSeverity | null;
150
- readonly highestConfidence: number;
151
- readonly actions: readonly ATRAction[];
152
- readonly matches: readonly ATRMatch[];
153
- readonly timestamp: string;
154
- }
155
- /** Result of executing a single action */
156
- export interface ActionResult {
157
- readonly action: ATRAction;
158
- readonly success: boolean;
159
- readonly message: string;
160
- readonly timestamp: string;
161
- }
162
- /** Context provided to platform adapters when executing actions */
163
- export interface ExecutionContext {
164
- readonly event: AgentEvent;
165
- readonly matches: readonly ATRMatch[];
166
- readonly verdict: ATRVerdict;
167
- readonly sessionId?: string;
168
- readonly metadata?: Readonly<Record<string, unknown>>;
169
- }
170
- /** Platform-specific adapter for executing ATR actions */
171
- export interface PlatformAdapter {
172
- readonly name: string;
173
- blockInput(ctx: ExecutionContext): Promise<ActionResult>;
174
- blockOutput(ctx: ExecutionContext): Promise<ActionResult>;
175
- blockTool(ctx: ExecutionContext): Promise<ActionResult>;
176
- quarantineSession(ctx: ExecutionContext): Promise<ActionResult>;
177
- resetContext(ctx: ExecutionContext): Promise<ActionResult>;
178
- alert(ctx: ExecutionContext): Promise<ActionResult>;
179
- snapshot(ctx: ExecutionContext): Promise<ActionResult>;
180
- escalate(ctx: ExecutionContext): Promise<ActionResult>;
181
- reducePermissions(ctx: ExecutionContext): Promise<ActionResult>;
182
- killAgent(ctx: ExecutionContext): Promise<ActionResult>;
183
- }
184
- /** Hook input from Claude Code / agent host */
185
- export interface HookInput {
186
- readonly hook: 'PreToolUse' | 'PostToolUse';
187
- readonly tool_name: string;
188
- readonly tool_input: Readonly<Record<string, unknown>>;
189
- readonly session_id?: string;
190
- readonly timestamp?: string;
191
- }
192
- /** Hook output to Claude Code / agent host */
193
- export interface HookOutput {
194
- readonly decision: VerdictOutcome;
195
- readonly reason?: string;
196
- readonly message?: string;
197
- readonly matched_rules?: readonly string[];
198
- }
199
- /** Scan type: MCP runtime event scan vs SKILL.md static file scan */
200
- export type ScanType = 'mcp' | 'skill';
201
- /** Unified scan result produced by both evaluate() and scanSkill() paths */
202
- export interface ScanResult {
203
- readonly scan_type: ScanType;
204
- readonly content_hash: string;
205
- readonly input_file?: string;
206
- readonly timestamp: string;
207
- readonly rules_loaded: number;
208
- readonly matches: readonly ATRMatch[];
209
- readonly threat_count: number;
210
- }
211
- //# sourceMappingURL=types.d.ts.map