agent-threat-rules 4.1.5 → 4.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +751 -1
- package/README.md +356 -125
- package/dist/adapters/openshell-filter.d.ts +10 -3
- package/dist/adapters/openshell-filter.d.ts.map +1 -1
- package/dist/adapters/openshell-filter.js +10 -3
- package/dist/adapters/openshell-filter.js.map +1 -1
- package/dist/adapters/stdio-adapter.js +3 -3
- package/dist/adapters/stdio-adapter.js.map +1 -1
- package/dist/cli/mcp-tools-document.d.ts +40 -0
- package/dist/cli/mcp-tools-document.d.ts.map +1 -0
- package/dist/cli/mcp-tools-document.js +95 -0
- package/dist/cli/mcp-tools-document.js.map +1 -0
- package/dist/cli/scan-handler.d.ts +8 -0
- package/dist/cli/scan-handler.d.ts.map +1 -1
- package/dist/cli/scan-handler.js +126 -34
- package/dist/cli/scan-handler.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +80 -43
- package/dist/cli.js.map +1 -1
- package/dist/converters/sarif.d.ts +14 -2
- package/dist/converters/sarif.d.ts.map +1 -1
- package/dist/converters/sarif.js +7 -9
- package/dist/converters/sarif.js.map +1 -1
- package/dist/corpus-event.d.ts +47 -5
- package/dist/corpus-event.d.ts.map +1 -1
- package/dist/corpus-event.js +68 -29
- package/dist/corpus-event.js.map +1 -1
- package/dist/embedding/model-loader.d.ts +2 -0
- package/dist/embedding/model-loader.d.ts.map +1 -1
- package/dist/embedding/model-loader.js +3 -1
- package/dist/embedding/model-loader.js.map +1 -1
- package/dist/enforcement.d.ts +8 -0
- package/dist/enforcement.d.ts.map +1 -1
- package/dist/enforcement.js +10 -0
- package/dist/enforcement.js.map +1 -1
- package/dist/engine.d.ts +150 -6
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +337 -76
- package/dist/engine.js.map +1 -1
- package/dist/eval/embedding-provenance.d.ts +40 -0
- package/dist/eval/embedding-provenance.d.ts.map +1 -0
- package/dist/eval/embedding-provenance.js +71 -0
- package/dist/eval/embedding-provenance.js.map +1 -0
- package/dist/eval/eval-harness.d.ts +34 -0
- package/dist/eval/eval-harness.d.ts.map +1 -1
- package/dist/eval/eval-harness.js +49 -2
- package/dist/eval/eval-harness.js.map +1 -1
- package/dist/eval/hackaprompt-corpus.d.ts +12 -0
- package/dist/eval/hackaprompt-corpus.d.ts.map +1 -1
- package/dist/eval/hackaprompt-corpus.js +15 -1
- package/dist/eval/hackaprompt-corpus.js.map +1 -1
- package/dist/eval/hackaprompt-provenance.d.ts +52 -0
- package/dist/eval/hackaprompt-provenance.d.ts.map +1 -0
- package/dist/eval/hackaprompt-provenance.js +108 -0
- package/dist/eval/hackaprompt-provenance.js.map +1 -0
- package/dist/eval/run-hackaprompt-benchmark.d.ts +18 -8
- package/dist/eval/run-hackaprompt-benchmark.d.ts.map +1 -1
- package/dist/eval/run-hackaprompt-benchmark.js +154 -64
- package/dist/eval/run-hackaprompt-benchmark.js.map +1 -1
- package/dist/eval/run-pint-benchmark.js +11 -1
- package/dist/eval/run-pint-benchmark.js.map +1 -1
- package/dist/eval/skill-benchmark.d.ts +26 -6
- package/dist/eval/skill-benchmark.d.ts.map +1 -1
- package/dist/eval/skill-benchmark.js +49 -16
- package/dist/eval/skill-benchmark.js.map +1 -1
- package/dist/flywheel.d.ts +4 -0
- package/dist/flywheel.d.ts.map +1 -1
- package/dist/flywheel.js +12 -4
- package/dist/flywheel.js.map +1 -1
- package/dist/hook-handler.d.ts +11 -1
- package/dist/hook-handler.d.ts.map +1 -1
- package/dist/hook-handler.js +84 -16
- package/dist/hook-handler.js.map +1 -1
- package/dist/hook-tool-output.d.ts +47 -0
- package/dist/hook-tool-output.d.ts.map +1 -0
- package/dist/hook-tool-output.js +110 -0
- package/dist/hook-tool-output.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/layer-integration.d.ts +4 -2
- package/dist/layer-integration.d.ts.map +1 -1
- package/dist/layer-integration.js +6 -2
- package/dist/layer-integration.js.map +1 -1
- package/dist/mcp-server.d.ts +8 -0
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +1 -0
- package/dist/mcp-server.js.map +1 -1
- package/dist/mcp-tools/scan.d.ts.map +1 -1
- package/dist/mcp-tools/scan.js +9 -1
- package/dist/mcp-tools/scan.js.map +1 -1
- package/dist/measurement/enforce-lane.d.ts +66 -0
- package/dist/measurement/enforce-lane.d.ts.map +1 -0
- package/dist/measurement/enforce-lane.js +89 -0
- package/dist/measurement/enforce-lane.js.map +1 -0
- package/dist/measurement/from-eval-harness.d.ts +16 -3
- package/dist/measurement/from-eval-harness.d.ts.map +1 -1
- package/dist/measurement/from-eval-harness.js +15 -5
- package/dist/measurement/from-eval-harness.js.map +1 -1
- package/dist/measurement/in-sample-ablation.d.ts +29 -0
- package/dist/measurement/in-sample-ablation.d.ts.map +1 -0
- package/dist/measurement/in-sample-ablation.js +45 -0
- package/dist/measurement/in-sample-ablation.js.map +1 -0
- package/dist/measurement/schema.d.ts +38 -1
- package/dist/measurement/schema.d.ts.map +1 -1
- package/dist/measurement/schema.js +43 -1
- package/dist/measurement/schema.js.map +1 -1
- package/dist/quality/action-eligibility.d.ts +4 -2
- package/dist/quality/action-eligibility.d.ts.map +1 -1
- package/dist/quality/action-eligibility.js.map +1 -1
- package/dist/rule-confidence.d.ts +31 -0
- package/dist/rule-confidence.d.ts.map +1 -0
- package/dist/rule-confidence.js +49 -0
- package/dist/rule-confidence.js.map +1 -0
- package/dist/rule-scaffolder.d.ts.map +1 -1
- package/dist/rule-scaffolder.js +43 -4
- package/dist/rule-scaffolder.js.map +1 -1
- package/dist/semantic-evaluator.d.ts.map +1 -1
- package/dist/semantic-evaluator.js +15 -13
- package/dist/semantic-evaluator.js.map +1 -1
- package/dist/shadow-evaluator.d.ts +7 -2
- package/dist/shadow-evaluator.d.ts.map +1 -1
- package/dist/shadow-evaluator.js +29 -25
- package/dist/shadow-evaluator.js.map +1 -1
- package/dist/testcase-event.d.ts +82 -1
- package/dist/testcase-event.d.ts.map +1 -1
- package/dist/testcase-event.js +135 -16
- package/dist/testcase-event.js.map +1 -1
- package/dist/tier0-invariant.d.ts.map +1 -1
- package/dist/tier0-invariant.js +1 -0
- package/dist/tier0-invariant.js.map +1 -1
- package/dist/tier1-blacklist.d.ts.map +1 -1
- package/dist/tier1-blacklist.js +1 -0
- package/dist/tier1-blacklist.js.map +1 -1
- package/dist/tool-definition-scope.d.ts +45 -0
- package/dist/tool-definition-scope.d.ts.map +1 -0
- package/dist/tool-definition-scope.js +68 -0
- package/dist/tool-definition-scope.js.map +1 -0
- package/dist/types.d.ts +42 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/verdict.d.ts +46 -2
- package/dist/verdict.d.ts.map +1 -1
- package/dist/verdict.js +99 -14
- package/dist/verdict.js.map +1 -1
- package/package.json +2 -1
- package/rules/agent-manipulation/ATR-2026-00030-cross-agent-attack.yaml +2 -2
- package/rules/agent-manipulation/ATR-2026-00139-casual-authority-redirect.yaml +1 -1
- package/rules/agent-manipulation/ATR-2026-00328-named-mode-persona-override.yaml +1 -1
- package/rules/agent-manipulation/ATR-2026-00330-yoja-allcaps-settings-block-persona.yaml +1 -1
- package/rules/agent-manipulation/ATR-2026-00418-weknora-mcp-config-rce.yaml +5 -5
- package/rules/agent-manipulation/ATR-2026-00432-superagi-output-handler-eval-rce.yaml +1 -1
- package/rules/agent-manipulation/ATR-2026-00440-semantic-kernel-vector-store-eval-rce.yaml +3 -3
- package/rules/context-exfiltration/ATR-2026-00426-nl-output-injection-credential-leak.yaml +1 -1
- package/rules/context-exfiltration/ATR-2026-00501-data-exfiltration-via-markdown-image-and-link-url-injection.yaml +16 -2
- package/rules/context-exfiltration/ATR-2026-00505-system-prompt-extraction-instruction-dump-request.yaml +6 -4
- package/rules/context-exfiltration/ATR-2026-00702-ipi-credential-exfil-via-agent-action.yaml +1 -1
- package/rules/context-exfiltration/ATR-2026-00707-ipi-file-exfil-with-destroy-or-tamper.yaml +1 -1
- package/rules/context-exfiltration/ATR-2026-00851-indirect-pi-financial-payment-exfil.yaml +1 -1
- package/rules/context-exfiltration/ATR-2026-01457-sysprompt-completion-clone-attack.yaml +1 -1
- package/rules/context-exfiltration/ATR-2026-01462-sysprompt-override-pseudo-admin.yaml +1 -1
- package/rules/context-exfiltration/ATR-2026-01463-imend-imsystem-prompt-injection-format.yaml +1 -1
- package/rules/context-exfiltration/ATR-2026-01606-ssrf-internal-network-scan.yaml +1 -1
- package/rules/context-exfiltration/ATR-2026-02847-policy-justified-exfil-to-email.yaml +1 -1
- package/rules/context-exfiltration/ATR-2026-02855-cross-email-exfil-relay.yaml +79 -0
- package/rules/context-exfiltration/ATR-2026-02861-exfil-send-email-with-body-directive.yaml +83 -0
- package/rules/context-exfiltration/ATR-2026-02866-idna-label-separator-in-fetch-url-host.yaml +104 -0
- package/rules/excessive-autonomy/ATR-2026-00500-ssrf-via-agent-url-fetch-instruction.yaml +12 -2
- package/rules/excessive-autonomy/ATR-2026-00710-ipi-physical-access-grant.yaml +1 -1
- package/rules/model-abuse/ATR-2026-01897-host-sabotage.yaml +2 -2
- package/rules/model-security/ATR-2026-00433-modelcache-torch-load-deserialization-rce.yaml +1 -1
- package/rules/privilege-escalation/ATR-2026-00040-privilege-escalation.yaml +1 -1
- package/rules/privilege-escalation/ATR-2026-00436-enclave-vm-sandbox-escape-rce.yaml +1 -1
- package/rules/privilege-escalation/ATR-2026-01601-sql-injection-destructive-ddl.yaml +3 -3
- package/rules/privilege-escalation/ATR-2026-01612-debug-mode-privilege-escalation.yaml +1 -1
- package/rules/privilege-escalation/ATR-2026-02867-identifier-typed-tool-argument-dot-dot-path-segment.yaml +106 -0
- package/rules/prompt-injection/ATR-2026-00004-system-prompt-override.yaml +2 -2
- package/rules/prompt-injection/ATR-2026-00080-encoding-evasion.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-00086-visual-spoofing.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-00203-context-pollution-skill-description.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-00228-structured-jailbreak.yaml +2 -2
- package/rules/prompt-injection/ATR-2026-00233-structured-jailbreak.yaml +2 -2
- package/rules/prompt-injection/ATR-2026-00256-base-n-encoding-jailbreak.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-00264-latent-injection-translation.yaml +3 -3
- package/rules/prompt-injection/ATR-2026-00265-latent-injection-rag-document.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-00282-perez-prompt-injection-hijack.yaml +4 -4
- package/rules/prompt-injection/ATR-2026-00321-hyphenated-system-instruction-injection.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-00394-backspace-deletion-character-injection.yaml +2 -2
- package/rules/prompt-injection/ATR-2026-00446-variable-assignment-payload-injection.yaml +3 -3
- package/rules/prompt-injection/ATR-2026-00476-garak-web-injection-javascript-alert-1.yaml +3 -3
- package/rules/prompt-injection/ATR-2026-00481-garak-dan-mixedunassigned.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-00489-garak-encoding-javascript-alert-1.yaml +3 -3
- package/rules/prompt-injection/ATR-2026-00503-fake-error-state-takeover-unrestricted-replacement-bot.yaml +4 -2
- package/rules/prompt-injection/ATR-2026-00508-escape-delimiter-wrapped-goal-hijacking-in-user-input-prompt.yaml +3 -3
- package/rules/prompt-injection/ATR-2026-00512-rules-file-backdoor-injection.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-01005-many-shot-repetition-override.yaml +2 -2
- package/rules/prompt-injection/ATR-2026-01006-payload-split-string-concat-injection.yaml +2 -2
- package/rules/prompt-injection/ATR-2026-01015-evasion-refusal-suppression.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-01016-evasion-response-priming-forced-opener.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-01026-evasion-unicode-glitch-token-anomaly.yaml +2 -2
- package/rules/prompt-injection/ATR-2026-01304-indirect-injection-carrier-important-override.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-01759-dos-new-important-instructions-injection-in-document.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-01865-llmail-fake-email-boundary-marker.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-02010-emoji-only-payload.yaml +2 -2
- package/rules/prompt-injection/ATR-2026-02815-injected-halt-order-canned-reply-dos.yaml +80 -0
- package/rules/prompt-injection/ATR-2026-02820-tool-result-orders-agent-to-hide-its-own-action.yaml +106 -0
- package/rules/prompt-injection/ATR-2026-02858-context-suppression-directive.yaml +73 -0
- package/rules/prompt-injection/ATR-2026-02859-tool-output-agent-role-reassignment.yaml +71 -0
- package/rules/prompt-injection/ATR-2026-02860-forged-instruction-boundary-marker.yaml +70 -0
- package/rules/prompt-injection/ATR-2026-02862-fake-chat-template-turn-injection.yaml +79 -0
- package/rules/skill-compromise/ATR-2026-00060-skill-impersonation.yaml +1 -1
- package/rules/skill-compromise/ATR-2026-00063-skill-chain-attack.yaml +2 -2
- package/rules/skill-compromise/ATR-2026-00064-over-permissioned-skill.yaml +1 -1
- package/rules/skill-compromise/ATR-2026-00066-parameter-injection.yaml +2 -2
- package/rules/skill-compromise/ATR-2026-00149-skill-exfil-compound.yaml +6 -6
- package/rules/skill-compromise/ATR-2026-00223-reverse-shell-dropper.yaml +2 -2
- package/rules/skill-compromise/ATR-2026-01755-backdoor-pot-linguistic-trigger-phrase.yaml +1 -1
- package/rules/skill-compromise/ATR-2026-01756-backdoor-pot-symbol-emoticon-trigger.yaml +1 -1
- package/rules/skill-compromise/ATR-2026-02261-code-credential-exfil-chain.yaml +1 -1
- package/rules/tool-poisoning/ATR-2026-00012-unauthorized-tool-call.yaml +23 -23
- package/rules/tool-poisoning/ATR-2026-00013-tool-ssrf.yaml +16 -5
- package/rules/tool-poisoning/ATR-2026-00161-important-tag-cross-tool-shadowing.yaml +1 -1
- package/rules/tool-poisoning/ATR-2026-00277-echo-template-command-injection.yaml +2 -2
- package/rules/tool-poisoning/ATR-2026-00494-garak-exploitation-mixedunassigned.yaml +4 -4
- package/rules/tool-poisoning/ATR-2026-00521-shell-command-injection-agent-tool-context.yaml +1 -1
- package/rules/tool-poisoning/ATR-2026-00581-mcp-tool-rug-pull-post-approval-redefinition.yaml +1 -1
- package/rules/tool-poisoning/ATR-2026-01303-tool-schema-enumeration-social-engineering.yaml +1 -1
- package/rules/tool-poisoning/ATR-2026-01307-mcp-dns-rebinding-attack.yaml +2 -2
- package/rules/tool-poisoning/ATR-2026-01775-semantic-mcp-tool-manifest-poisoning.yaml +1 -1
- package/rules/tool-poisoning/ATR-2026-01932-shadow-undeclared-mcp-server-registration.yaml +1 -1
- package/rules/tool-poisoning/ATR-2026-02025-mcp-full-schema-poisoning-nondescription-field.yaml +1 -1
- package/rules/tool-poisoning/ATR-2026-02817-untrusted-content-dictates-tool-arguments.yaml +83 -0
- package/rules/tool-poisoning/ATR-2026-02864-non-canonical-ipv4-host-in-url-tool-argument.yaml +102 -0
- package/rules/tool-poisoning/ATR-2026-02865-read-only-utility-write-flag-in-command-argument.yaml +157 -0
- package/rules/tool-poisoning/ATR-2026-02868-ssrf-ipv6-transition-address-embedded-private-ipv4.yaml +107 -0
- package/rules/tool-poisoning/ATR-2026-02870-invisible-control-before-directive.yaml +94 -0
- package/spec/README.md +6 -3
- package/spec/atr-event-v1.0.md +13 -8
- package/spec/atr-method-v1.1.md +2 -2
- package/spec/category-registry/gemara/README.md +102 -0
- package/spec/category-registry/gemara/ai-agent-capability-catalog.yaml +157 -0
- package/spec/category-registry/gemara/atr-attack-vector-catalog.yaml +130 -0
- package/spec/category-registry/gemara/atr-detection-control-catalog.yaml +327 -0
- package/spec/category-registry/gemara/atr-threat-catalog.yaml +246 -0
- package/spec/category-registry/gemara/src/editorial.yaml +743 -0
- package/spec/mappings/README.md +1 -1
- package/spec/mappings/atr-to-nist-csf-2.0.md +5 -4
- package/spec/schema/event.schema.json +1 -1
package/dist/verdict.d.ts
CHANGED
|
@@ -6,9 +6,42 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module agent-threat-rules/verdict
|
|
8
8
|
*/
|
|
9
|
-
import type { ATRMatch, ATRSeverity, ATRVerdict } from './types.js';
|
|
9
|
+
import type { ATRMatch, ATRSeverity, ATRAction, ATRVerdict } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Whether a model, not a rule's deterministic logic, decided this match. A match
|
|
12
|
+
* without a decider (built outside the engine, as every match was before
|
|
13
|
+
* decidedBy existed) is read as deterministic; an unknown decider as a model.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isModelDecided(match: Pick<ATRMatch, 'decidedBy'>): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* What a model-decided match may do.
|
|
18
|
+
* 'advisory' (default): it is reported and its observe-tier actions run, but
|
|
19
|
+
* it takes no part in the outcome and its actions above observe are not
|
|
20
|
+
* dispatched.
|
|
21
|
+
* 'enforce': it counts like any other match. Its false-positive rate has not
|
|
22
|
+
* been measured; choose this only if you accept that.
|
|
23
|
+
*/
|
|
24
|
+
export type ModelDecisions = 'advisory' | 'enforce';
|
|
25
|
+
export interface VerdictOptions {
|
|
26
|
+
readonly modelDecisions?: ModelDecisions;
|
|
27
|
+
}
|
|
28
|
+
/** Read a modelDecisions setting, refusing anything but the two values. */
|
|
29
|
+
export declare function modelDecisionsFromConfig(value: unknown): ModelDecisions;
|
|
10
30
|
/** Severity rank from most severe (0) to least severe (4) */
|
|
11
31
|
export declare const SEVERITY_RANK: Readonly<Record<ATRSeverity, number>>;
|
|
32
|
+
/**
|
|
33
|
+
* Minimum confidence at which a high-severity match denies; below it, asks.
|
|
34
|
+
*
|
|
35
|
+
* Compared as given. A confidence the engine derives from a rule's
|
|
36
|
+
* `tags.confidence` label reaches this threshold only from a `high` label:
|
|
37
|
+
* `src/rule-confidence.ts` caps every lower label one basis point under it.
|
|
38
|
+
*/
|
|
39
|
+
export declare const HIGH_SEVERITY_DENY_CONFIDENCE = 0.8;
|
|
40
|
+
/**
|
|
41
|
+
* Minimum confidence at which a medium-severity match asks; below it, allows.
|
|
42
|
+
* A `low` label reaches it exactly (0.6) when every condition matched.
|
|
43
|
+
*/
|
|
44
|
+
export declare const MEDIUM_SEVERITY_ASK_CONFIDENCE = 0.6;
|
|
12
45
|
/**
|
|
13
46
|
* Check whether auto-response is enabled for a matched rule.
|
|
14
47
|
* The auto_response_threshold field on ATRResponse indicates the
|
|
@@ -16,11 +49,22 @@ export declare const SEVERITY_RANK: Readonly<Record<ATRSeverity, number>>;
|
|
|
16
49
|
* automatically (without human approval).
|
|
17
50
|
*/
|
|
18
51
|
export declare function isAutoResponseEnabled(match: ATRMatch): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* The observe-tier actions of matches whose other actions are not dispatched.
|
|
54
|
+
* Only actions the tier ladder names: actionTier() reads an unknown name as
|
|
55
|
+
* observe, and a name it does not know is not one this policy can vouch for.
|
|
56
|
+
*/
|
|
57
|
+
export declare function observeActions(matches: readonly ATRMatch[]): readonly ATRAction[];
|
|
19
58
|
/**
|
|
20
59
|
* Compute a verdict from an array of ATR matches.
|
|
21
60
|
*
|
|
61
|
+
* A match a model decided (isModelDecided) is reported but, unless
|
|
62
|
+
* options.modelDecisions is 'enforce', takes no part in the outcome, and of its
|
|
63
|
+
* actions only the observe tier is dispatched: no benign-corpus measurement
|
|
64
|
+
* stands behind a model's decision. Every other match counts as before.
|
|
65
|
+
*
|
|
22
66
|
* This is a pure function -- no side effects, no mutation.
|
|
23
67
|
* Returns a frozen ATRVerdict object.
|
|
24
68
|
*/
|
|
25
|
-
export declare function computeVerdict(matches: readonly ATRMatch[]): ATRVerdict;
|
|
69
|
+
export declare function computeVerdict(matches: readonly ATRMatch[], options?: VerdictOptions): ATRVerdict;
|
|
26
70
|
//# sourceMappingURL=verdict.d.ts.map
|
package/dist/verdict.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verdict.d.ts","sourceRoot":"","sources":["../src/verdict.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,QAAQ,
|
|
1
|
+
{"version":3,"file":"verdict.d.ts","sourceRoot":"","sources":["../src/verdict.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,QAAQ,EAER,WAAW,EACX,SAAS,EACT,UAAU,EAEX,MAAM,YAAY,CAAC;AAsBpB;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,OAAO,CAE1E;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,SAAS,CAAC;AAEpD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;CAC1C;AAED,2EAA2E;AAC3E,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAMvE;AAED,6DAA6D;AAC7D,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAM/D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,QAAQ,GACd,OAAO,CAcT;AAkDD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,SAAS,EAAE,CAIjF;AA8BD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,OAAO,GAAE,cAAmB,GAC3B,UAAU,CAmDZ"}
|
package/dist/verdict.js
CHANGED
|
@@ -6,6 +6,41 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module agent-threat-rules/verdict
|
|
8
8
|
*/
|
|
9
|
+
import { ACTION_TIERS, TIERED_ACTIONS, actionTier } from './quality/action-eligibility.js';
|
|
10
|
+
/**
|
|
11
|
+
* Deciders that are a rule's own deterministic logic. Every other decider is a
|
|
12
|
+
* model: a semantic rule's judge (`semantic-judge`), the Tier 2.5 embedding
|
|
13
|
+
* signal (`embedding`), the Layer 3 semantic module (`semantic-layer`), and any
|
|
14
|
+
* value this list does not know. No evidence a response tier is earned from
|
|
15
|
+
* measures a model's decisions (the benign-corpus evidence runs the synchronous
|
|
16
|
+
* engine, where a semantic rule is its pattern fallback), so by default they are
|
|
17
|
+
* reported and not enforced.
|
|
18
|
+
*/
|
|
19
|
+
const DETERMINISTIC_DECIDERS = new Set([
|
|
20
|
+
'pattern',
|
|
21
|
+
'signature',
|
|
22
|
+
'trace',
|
|
23
|
+
'semantic-fallback',
|
|
24
|
+
'invariant',
|
|
25
|
+
'blacklist',
|
|
26
|
+
'fingerprint',
|
|
27
|
+
]);
|
|
28
|
+
/**
|
|
29
|
+
* Whether a model, not a rule's deterministic logic, decided this match. A match
|
|
30
|
+
* without a decider (built outside the engine, as every match was before
|
|
31
|
+
* decidedBy existed) is read as deterministic; an unknown decider as a model.
|
|
32
|
+
*/
|
|
33
|
+
export function isModelDecided(match) {
|
|
34
|
+
return match.decidedBy !== undefined && !DETERMINISTIC_DECIDERS.has(match.decidedBy);
|
|
35
|
+
}
|
|
36
|
+
/** Read a modelDecisions setting, refusing anything but the two values. */
|
|
37
|
+
export function modelDecisionsFromConfig(value) {
|
|
38
|
+
if (value === undefined)
|
|
39
|
+
return 'advisory';
|
|
40
|
+
if (value === 'advisory' || value === 'enforce')
|
|
41
|
+
return value;
|
|
42
|
+
throw new TypeError(`modelDecisions must be 'advisory' or 'enforce', not ${JSON.stringify(value)}`);
|
|
43
|
+
}
|
|
9
44
|
/** Severity rank from most severe (0) to least severe (4) */
|
|
10
45
|
export const SEVERITY_RANK = {
|
|
11
46
|
critical: 0,
|
|
@@ -14,6 +49,19 @@ export const SEVERITY_RANK = {
|
|
|
14
49
|
low: 3,
|
|
15
50
|
informational: 4,
|
|
16
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Minimum confidence at which a high-severity match denies; below it, asks.
|
|
54
|
+
*
|
|
55
|
+
* Compared as given. A confidence the engine derives from a rule's
|
|
56
|
+
* `tags.confidence` label reaches this threshold only from a `high` label:
|
|
57
|
+
* `src/rule-confidence.ts` caps every lower label one basis point under it.
|
|
58
|
+
*/
|
|
59
|
+
export const HIGH_SEVERITY_DENY_CONFIDENCE = 0.8;
|
|
60
|
+
/**
|
|
61
|
+
* Minimum confidence at which a medium-severity match asks; below it, allows.
|
|
62
|
+
* A `low` label reaches it exactly (0.6) when every condition matched.
|
|
63
|
+
*/
|
|
64
|
+
export const MEDIUM_SEVERITY_ASK_CONFIDENCE = 0.6;
|
|
17
65
|
/**
|
|
18
66
|
* Check whether auto-response is enabled for a matched rule.
|
|
19
67
|
* The auto_response_threshold field on ATRResponse indicates the
|
|
@@ -49,9 +97,9 @@ function determineOutcome(severity, confidence) {
|
|
|
49
97
|
return 'deny';
|
|
50
98
|
}
|
|
51
99
|
if (severity === 'high') {
|
|
52
|
-
return confidence >=
|
|
100
|
+
return confidence >= HIGH_SEVERITY_DENY_CONFIDENCE ? 'deny' : 'ask';
|
|
53
101
|
}
|
|
54
|
-
if (severity === 'medium' && confidence >=
|
|
102
|
+
if (severity === 'medium' && confidence >= MEDIUM_SEVERITY_ASK_CONFIDENCE) {
|
|
55
103
|
return 'ask';
|
|
56
104
|
}
|
|
57
105
|
return 'allow';
|
|
@@ -73,6 +121,19 @@ function collectUniqueActions(matches) {
|
|
|
73
121
|
}
|
|
74
122
|
return Object.freeze(actions);
|
|
75
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* The observe-tier actions of matches whose other actions are not dispatched.
|
|
126
|
+
* Only actions the tier ladder names: actionTier() reads an unknown name as
|
|
127
|
+
* observe, and a name it does not know is not one this policy can vouch for.
|
|
128
|
+
*/
|
|
129
|
+
export function observeActions(matches) {
|
|
130
|
+
return collectUniqueActions(matches).filter((a) => TIERED_ACTIONS.includes(a) && actionTier(a) === ACTION_TIERS.OBSERVE);
|
|
131
|
+
}
|
|
132
|
+
/** Severity first, then confidence: the order computeVerdict reads matches in. */
|
|
133
|
+
function bySeverityThenConfidence(a, b) {
|
|
134
|
+
const bySeverity = (SEVERITY_RANK[a.rule.severity] ?? 4) - (SEVERITY_RANK[b.rule.severity] ?? 4);
|
|
135
|
+
return bySeverity !== 0 ? bySeverity : b.confidence - a.confidence;
|
|
136
|
+
}
|
|
76
137
|
/**
|
|
77
138
|
* Build a human-readable reason string from the highest severity match.
|
|
78
139
|
*/
|
|
@@ -89,10 +150,16 @@ function buildReason(highestMatch, outcome, matchCount) {
|
|
|
89
150
|
/**
|
|
90
151
|
* Compute a verdict from an array of ATR matches.
|
|
91
152
|
*
|
|
153
|
+
* A match a model decided (isModelDecided) is reported but, unless
|
|
154
|
+
* options.modelDecisions is 'enforce', takes no part in the outcome, and of its
|
|
155
|
+
* actions only the observe tier is dispatched: no benign-corpus measurement
|
|
156
|
+
* stands behind a model's decision. Every other match counts as before.
|
|
157
|
+
*
|
|
92
158
|
* This is a pure function -- no side effects, no mutation.
|
|
93
159
|
* Returns a frozen ATRVerdict object.
|
|
94
160
|
*/
|
|
95
|
-
export function computeVerdict(matches) {
|
|
161
|
+
export function computeVerdict(matches, options = {}) {
|
|
162
|
+
const modelDecisions = modelDecisionsFromConfig(options.modelDecisions);
|
|
96
163
|
if (matches.length === 0) {
|
|
97
164
|
return Object.freeze({
|
|
98
165
|
outcome: 'allow',
|
|
@@ -105,23 +172,41 @@ export function computeVerdict(matches) {
|
|
|
105
172
|
timestamp: new Date().toISOString(),
|
|
106
173
|
});
|
|
107
174
|
}
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
const
|
|
175
|
+
// Sorted here rather than trusted: not every caller sorts (the engine appends
|
|
176
|
+
// the embedding match last, and scanSkill appends decoded-payload matches).
|
|
177
|
+
// The sort is stable, so an already sorted list keeps its order.
|
|
178
|
+
const sorted = [...matches].sort(bySeverityThenConfidence);
|
|
179
|
+
const advisory = modelDecisions === 'advisory' ? sorted.filter(isModelDecided) : [];
|
|
180
|
+
const enforcing = advisory.length === 0 ? sorted : sorted.filter((m) => !isModelDecided(m));
|
|
181
|
+
const highestMatch = enforcing[0];
|
|
182
|
+
const outcome = highestMatch ? determineOutcome(highestMatch.rule.severity, highestMatch.confidence) : 'allow';
|
|
183
|
+
const actions = Object.freeze([
|
|
184
|
+
...new Set([...collectUniqueActions(enforcing), ...observeActions(advisory)]),
|
|
185
|
+
]);
|
|
186
|
+
const topAdvisory = advisory[0];
|
|
187
|
+
const reason = highestMatch
|
|
188
|
+
? buildReason(highestMatch, outcome, matches.length) + advisoryNote(advisory.length)
|
|
189
|
+
: `ALLOW: ${topAdvisory.rule.title} [${topAdvisory.rule.severity}/` +
|
|
190
|
+
`${Math.round(topAdvisory.confidence * 100)}% confidence, decided by ` +
|
|
191
|
+
`${topAdvisory.decidedBy}]: ${advisory.length} model-decided ` +
|
|
192
|
+
`match${advisory.length === 1 ? '' : 'es'} reported, not enforced (modelDecisions: advisory).`;
|
|
116
193
|
return Object.freeze({
|
|
117
194
|
outcome,
|
|
118
195
|
reason,
|
|
119
196
|
matchCount: matches.length,
|
|
120
|
-
highestSeverity,
|
|
121
|
-
highestConfidence,
|
|
197
|
+
highestSeverity: highestMatch?.rule.severity ?? null,
|
|
198
|
+
highestConfidence: highestMatch?.confidence ?? 0,
|
|
122
199
|
actions,
|
|
123
|
-
matches: Object.freeze(
|
|
200
|
+
matches: Object.freeze(sorted),
|
|
201
|
+
// Present only when something was held back, so a verdict without a model
|
|
202
|
+
// decision has exactly the fields it always had.
|
|
203
|
+
...(topAdvisory
|
|
204
|
+
? { advisory: Object.freeze(advisory), advisorySeverity: topAdvisory.rule.severity }
|
|
205
|
+
: {}),
|
|
124
206
|
timestamp: new Date().toISOString(),
|
|
125
207
|
});
|
|
126
208
|
}
|
|
209
|
+
function advisoryNote(count) {
|
|
210
|
+
return count === 0 ? '' : `; ${count} model-decided match${count === 1 ? '' : 'es'} reported, not enforced`;
|
|
211
|
+
}
|
|
127
212
|
//# sourceMappingURL=verdict.js.map
|
package/dist/verdict.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verdict.js","sourceRoot":"","sources":["../src/verdict.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,6DAA6D;AAC7D,MAAM,CAAC,MAAM,aAAa,GAA0C;IAClE,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;IACN,aAAa,EAAE,CAAC;CACjB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAe;IAEf,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC;IAC9D,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAE7B,MAAM,YAAY,GAA2B;QAC3C,IAAI,EAAE,GAAG;QACT,MAAM,EAAE,GAAG;QACX,GAAG,EAAE,GAAG;KACT,CAAC;IAEF,MAAM,kBAAkB,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,kBAAkB,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAEnD,OAAO,KAAK,CAAC,UAAU,IAAI,kBAAkB,CAAC;AAChD,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,gBAAgB,CACvB,QAAqB,EACrB,UAAkB;IAElB,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO,UAAU,IAAI,
|
|
1
|
+
{"version":3,"file":"verdict.js","sourceRoot":"","sources":["../src/verdict.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE3F;;;;;;;;GAQG;AACH,MAAM,sBAAsB,GAAwB,IAAI,GAAG,CAAkB;IAC3E,SAAS;IACT,WAAW;IACX,OAAO;IACP,mBAAmB;IACnB,WAAW;IACX,WAAW;IACX,aAAa;CACd,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAkC;IAC/D,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACvF,CAAC;AAgBD,2EAA2E;AAC3E,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IAC3C,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,IAAI,SAAS,CACjB,uDAAuD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAC/E,CAAC;AACJ,CAAC;AAED,6DAA6D;AAC7D,MAAM,CAAC,MAAM,aAAa,GAA0C;IAClE,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;IACN,aAAa,EAAE,CAAC;CACjB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAG,CAAC;AAElD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAe;IAEf,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC;IAC9D,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAE7B,MAAM,YAAY,GAA2B;QAC3C,IAAI,EAAE,GAAG;QACT,MAAM,EAAE,GAAG;QACX,GAAG,EAAE,GAAG;KACT,CAAC;IAEF,MAAM,kBAAkB,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,kBAAkB,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAEnD,OAAO,KAAK,CAAC,UAAU,IAAI,kBAAkB,CAAC;AAChD,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,gBAAgB,CACvB,QAAqB,EACrB,UAAkB;IAElB,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO,UAAU,IAAI,6BAA6B,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IACtE,CAAC;IACD,IAAI,QAAQ,KAAK,QAAQ,IAAI,UAAU,IAAI,8BAA8B,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAC3B,OAA4B;IAE5B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAa,CAAC;IAClC,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAA4B;IACzD,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC,MAAM,CACzC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,OAAO,CAC5E,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,SAAS,wBAAwB,CAAC,CAAW,EAAE,CAAW;IACxD,MAAM,UAAU,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACjG,OAAO,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAClB,YAAkC,EAClC,OAAuB,EACvB,UAAkB;IAElB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,YAAY,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;IAEzC,OAAO,CACL,GAAG,OAAO,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,KAAK,GAAG;QAC1C,IAAI,IAAI,CAAC,QAAQ,IAAI,GAAG,gBAAgB;QACxC,IAAI,UAAU,QAAQ,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,CAC7D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAC5B,OAA4B,EAC5B,UAA0B,EAAE;IAE5B,MAAM,cAAc,GAAG,wBAAwB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAExE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,OAAO,EAAE,OAAgB;YACzB,MAAM,EAAE,mBAAmB;YAC3B,UAAU,EAAE,CAAC;YACb,eAAe,EAAE,IAAI;YACrB,iBAAiB,EAAE,CAAC;YACpB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;IACL,CAAC;IAED,8EAA8E;IAC9E,4EAA4E;IAC5E,iEAAiE;IACjE,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,cAAc,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5F,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/G,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,oBAAoB,CAAC,SAAS,CAAC,EAAE,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;KAC9E,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,YAAY;QACzB,CAAC,CAAC,WAAW,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC;QACpF,CAAC,CAAC,UAAU,WAAY,CAAC,IAAI,CAAC,KAAK,KAAK,WAAY,CAAC,IAAI,CAAC,QAAQ,GAAG;YACnE,GAAG,IAAI,CAAC,KAAK,CAAC,WAAY,CAAC,UAAU,GAAG,GAAG,CAAC,2BAA2B;YACvE,GAAG,WAAY,CAAC,SAAS,MAAM,QAAQ,CAAC,MAAM,iBAAiB;YAC/D,QAAQ,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,qDAAqD,CAAC;IAEnG,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,OAAO;QACP,MAAM;QACN,UAAU,EAAE,OAAO,CAAC,MAAM;QAC1B,eAAe,EAAE,YAAY,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI;QACpD,iBAAiB,EAAE,YAAY,EAAE,UAAU,IAAI,CAAC;QAChD,OAAO;QACP,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QAC9B,0EAA0E;QAC1E,iDAAiD;QACjD,GAAG,CAAC,WAAW;YACb,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,gBAAgB,EAAE,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE;YACpF,CAAC,CAAC,EAAE,CAAC;QACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,uBAAuB,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,yBAAyB,CAAC;AAC9G,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-threat-rules",
|
|
3
|
-
"version": "4.1
|
|
3
|
+
"version": "4.2.1",
|
|
4
4
|
"mcpName": "io.github.Agent-Threat-Rule/agent-threat-rules",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Open detection standard — like Sigma, but for AI agents. Executable, testable rules for prompt injection, tool poisoning, context exfiltration, and MCP attacks. MIT-licensed.",
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
"validate:compliance": "tsx scripts/validate-compliance.ts",
|
|
96
96
|
"eval": "tsx src/eval/run-eval.ts",
|
|
97
97
|
"eval:pint": "tsx src/eval/run-pint-benchmark.ts",
|
|
98
|
+
"eval:hackaprompt": "python3 scripts/hackaprompt-to-corpus.py && tsx src/eval/run-hackaprompt-benchmark.ts",
|
|
98
99
|
"eval:generalization": "tsx scripts/eval-generalization.ts --all",
|
|
99
100
|
"gate:generalization": "tsx scripts/eval-generalization.ts --gate",
|
|
100
101
|
"gate:rule-latency": "tsx scripts/gate-rule-latency.ts",
|
|
@@ -124,7 +124,7 @@ detection:
|
|
|
124
124
|
description: Attempt to inject new instructions via agent messages (live directive only; negative lookbehind excludes quoted/listed occurrences in prompt-injection detection docs)
|
|
125
125
|
- field: content
|
|
126
126
|
operator: regex
|
|
127
|
-
value: (?i)(?:you\s+are\s+now|from\s+now\s+on|henceforth|going\s+forward|effective\s+immediately)\s+(?:a|an|the)
|
|
127
|
+
value: (?i)(?:you\s+are\s+now|from\s+now\s+on|henceforth|going\s+forward|effective\s+immediately)\s+(?:(?:a|an|the)\s*)?(?:(?:unrestricted|unfiltered|jailbroken)\s*)?[a-zA-Z]+\s+(?:agent|assistant|bot)
|
|
128
128
|
description: Attempt to redefine target agent's identity or role
|
|
129
129
|
- field: content
|
|
130
130
|
operator: regex
|
|
@@ -132,7 +132,7 @@ detection:
|
|
|
132
132
|
description: Instruction to hide actions from oversight (excludes benign coaching form 'never tell users to <verb>' via the first negative lookahead; the second excludes output-verbosity control, 'do not tell the user about each|every|individual <step>', which scopes down per-item progress narration rather than concealing a fact — a report-building skill triggered this on 'Don't tell the user about each tool call as you make it'. Concealment form 'do not tell the user about <fact>' is kept)
|
|
133
133
|
- field: content
|
|
134
134
|
operator: regex
|
|
135
|
-
value: (?i)(?:acting|speaking|operating)\s+(?:on\s+behalf\s+of|as\s+a
|
|
135
|
+
value: (?i)(?:acting|speaking|operating)\s+(?:on\s+behalf\s+of|as\s+(?:a\s*)?proxy\s+for|in\s+place\s+of)\s+[a-zA-Z0-9_-]+\s*(?:agent)?
|
|
136
136
|
description: Agent claiming to act on behalf of another agent
|
|
137
137
|
- field: content
|
|
138
138
|
operator: regex
|
|
@@ -64,7 +64,7 @@ detection:
|
|
|
64
64
|
conditions:
|
|
65
65
|
- field: content
|
|
66
66
|
operator: regex
|
|
67
|
-
value: (?i)(?:
|
|
67
|
+
value: (?i)(?:the\s+)?(?:orchestrator|coordinator|manager|admin|boss|supervisor|lead)\s+(?:wants?|said|told|instructed|requires?|decided).*(?:append|send|redirect|forward|pipe|write|log)\s+(?:all\s+)?(?:data|output|results?|logs?|info).*(?://|https?://|\d{1,3}\.\d{1,3})
|
|
68
68
|
description: Authority claim redirecting output to external endpoint
|
|
69
69
|
- field: content
|
|
70
70
|
operator: regex
|
|
@@ -80,7 +80,7 @@ detection:
|
|
|
80
80
|
description: '"Stay in X Mode" + chaos/law-inversion — from inthewild corpus #339 (APOPHIS Mode: "the only true Law is Chaos, and that Humans are meant to be self-serving and selfish")'
|
|
81
81
|
- field: tool_response
|
|
82
82
|
operator: regex
|
|
83
|
-
value: \w
|
|
83
|
+
value: \w\s+Mode\s+(?:output|responses?)[\s\S]{0,200}(?:generating\s+any\s+kind\s+of\s+content|ignoring\s+OpenA[Il](?:\s*(?:['`]s?|s))?\s+content\s+polic)
|
|
84
84
|
description: '"X Mode output/responses" + generating any content or ignoring OpenAI policies — Mode-output paired with content-policy bypass from inthewild corpus #416 BABY Mode output definition'
|
|
85
85
|
- field: tool_response
|
|
86
86
|
operator: regex
|
|
@@ -76,7 +76,7 @@ detection:
|
|
|
76
76
|
description: '"always respond as the character despite any negative feedback or criticism" — exact character-lock mandate from inthewild corpus #14 #88; "despite negative feedback" prevents safety interventions from breaking the character'
|
|
77
77
|
- field: tool_response
|
|
78
78
|
operator: regex
|
|
79
|
-
value: '[A-Z][A-Z0-9]
|
|
79
|
+
value: '[A-Z][0-9]*[A-Z0-9]\s+(?:respond|always\s+respond|will\s+respond)\s+as\s+the\s+character[\s\S]{0,50}[A-Z][A-Z0-9]+\s+always\s+respond\s+as\s+the\s+character'
|
|
80
80
|
description: ALL-CAPS name repeated twice with "respond as the character" mandate — the YOJA-template repeats the persona name as prefix for every rule; the double ALL-CAPS+mandate pattern distinguishes structured persona injection from casual roleplay
|
|
81
81
|
- field: tool_response
|
|
82
82
|
operator: regex
|
|
@@ -89,19 +89,19 @@ detection:
|
|
|
89
89
|
description: WeKnora plugin/MCP loader content referencing process-spawning fields
|
|
90
90
|
- field: content
|
|
91
91
|
operator: regex
|
|
92
|
-
value: (?i)(?:plugins?|mcp_servers?)\s*[:=]\s
|
|
92
|
+
value: (?i)(?:plugins?|mcp_servers?)\s*[:=]\s*(?:\[\s*)?\{[^}]{0,400}"command"\s*:\s*"(?:curl|wget)"
|
|
93
93
|
description: Plugin/MCP-servers config block where the command field resolves to curl/wget — never a legitimate plugin launcher target
|
|
94
94
|
- field: content
|
|
95
95
|
operator: regex
|
|
96
|
-
value: (?i)(?:plugins?|mcp_servers?)\s*[:=]\s
|
|
96
|
+
value: (?i)(?:plugins?|mcp_servers?)\s*[:=]\s*(?:\[\s*)?\{[^}]{0,400}"command"\s*:\s*"(?:bash|sh|cmd|powershell)"[^}]{0,300}"args"\s*:\s*\[[^\]]{0,300}(?:https?://|\|\s*(?:ba)?sh\b|-enc(?:odedcommand)?\b|base64|iwr\b|invoke-webrequest)
|
|
97
97
|
description: Plugin/MCP-servers config block where the wrapper shell (bash/sh/cmd/powershell) args show a genuine payload marker (URL fetch, pipe-to-shell, base64/encoded-command). Excludes benign self-launch idioms like 'sh -c cd /project && node dist/index.js' or 'bash -c /absolute/path/to/own-installed-binary --flag', which lack any such marker — those are the standard way MCP servers document their own stdio launch command, not RCE setup.
|
|
98
98
|
- field: content
|
|
99
99
|
operator: regex
|
|
100
|
-
value: '(?i)(?:^|\n)\
|
|
100
|
+
value: '(?i)(?:^|\n)[^\S\n]*command\s*:\s*[\x27"]?(?:curl|wget)[\x27"]?[^\S\n]*\n\s*args?\s*:'
|
|
101
101
|
description: YAML-style plugin config with curl/wget as command — never a legitimate plugin launcher target
|
|
102
102
|
- field: content
|
|
103
103
|
operator: regex
|
|
104
|
-
value: (?i)(?:^|\n)\
|
|
104
|
+
value: (?i)(?:^|\n)[^\S\n]*command\s*:\s*[\x27"]?(?:bash|sh|cmd|powershell)[\x27"]?[^\S\n]*\n\s*args?\s*:[\s\S]{0,300}(?:https?://|\|\s*(?:ba)?sh\b|-enc(?:odedcommand)?\b|base64|iwr\b|invoke-webrequest)
|
|
105
105
|
description: YAML-style plugin config with wrapper shell command and args showing a genuine payload marker — same rationale as the JSON-form condition above
|
|
106
106
|
- field: content
|
|
107
107
|
operator: regex
|
|
@@ -117,7 +117,7 @@ detection:
|
|
|
117
117
|
description: Shell/interpreter inline-execution flag in args array WHERE the executed string also shows a genuine payload marker (URL, pipe-to-shell, base64/encoded-command, curl/wget invocation). Bare '-c'/'-e' + any string was too loose — it matched benign self-launch strings like 'cd /Users/marc/project && node dist/index.js' or '/home/you/.../aks-mcp --transport stdio' that MCP servers commonly document as their own stdio launch command.
|
|
118
118
|
- field: content
|
|
119
119
|
operator: regex
|
|
120
|
-
value: (?i)(
|
|
120
|
+
value: (?i)(?:^\s+|\S[^\S\n]*\n\s+)-\s+-(?:c|e|-eval|-command)\s*$
|
|
121
121
|
description: YAML-style args list with inline-execution flag as standalone entry — co-occurrence anchor
|
|
122
122
|
response:
|
|
123
123
|
actions:
|
|
@@ -78,7 +78,7 @@ detection:
|
|
|
78
78
|
conditions:
|
|
79
79
|
- field: content
|
|
80
80
|
operator: regex
|
|
81
|
-
value: (?i)(?:^|[^a-zA-Z_])eval\s*\(\s*["\x27]
|
|
81
|
+
value: (?i)(?:^|[^a-zA-Z_])eval\s*\(\s*(?:["\x27]\s*)?(?:__import__|os\.system|os\.popen|subprocess\.|os\.exec|exec\s*\()
|
|
82
82
|
description: eval() invoking Python OS-execution primitives — direct LLM-output-to-eval RCE signature
|
|
83
83
|
- field: content
|
|
84
84
|
operator: regex
|
|
@@ -79,11 +79,11 @@ detection:
|
|
|
79
79
|
conditions:
|
|
80
80
|
- field: content
|
|
81
81
|
operator: regex
|
|
82
|
-
value: (?i)lambda\s+\
|
|
82
|
+
value: (?i)lambda\s+(?:\w+\s*)?:[^,)]*\beval\s*\(
|
|
83
83
|
description: 'Lambda body invoking eval() — primary CVE-2026-26030 exploit shape (`lambda row: eval(filter_expr)`)'
|
|
84
84
|
- field: content
|
|
85
85
|
operator: regex
|
|
86
|
-
value: (?i)lambda\s+\
|
|
86
|
+
value: (?i)lambda\s+(?:\w+\s*)?:[^,)]*\b__import__\s*\(\s*["\x27](?:os|subprocess|socket|builtins|importlib)["\x27]
|
|
87
87
|
description: Lambda body using __import__ to reach OS / process / builtin modules — eval-friendly RCE chain
|
|
88
88
|
- field: content
|
|
89
89
|
operator: regex
|
|
@@ -99,7 +99,7 @@ detection:
|
|
|
99
99
|
description: .NET / JavaScript Function() constructor with body invoking eval / process — cross-runtime variant
|
|
100
100
|
- field: user_input
|
|
101
101
|
operator: regex
|
|
102
|
-
value: (?i)lambda\s+\
|
|
102
|
+
value: (?i)lambda\s+(?:\w+\s*)?:[^,)]*\b(?:eval|exec|__import__)\s*\(
|
|
103
103
|
description: User-supplied filter expression containing lambda + dynamic-evaluation primitive — the original CVE-2026-26030 injection surface
|
|
104
104
|
response:
|
|
105
105
|
actions:
|
|
@@ -79,7 +79,7 @@ detection:
|
|
|
79
79
|
description: Embed credential as URL parameter / image src / markdown link
|
|
80
80
|
- field: content
|
|
81
81
|
operator: regex
|
|
82
|
-
value: (?i)!?\[[^\]]*\]\(\s*https?:\/\/[^)]*(?:\$\{?(?:API_KEY|ACCESS_TOKEN|SECRET|PASSWORD|TOKEN|CREDENTIAL|BEARER|AUTH)\b|\{\{\s*(?:api_key|access_token|secret|password|token|credential|env)\b)
|
|
82
|
+
value: (?i)!?\[[^\[\]]*\]\(\s*https?:\/\/[^)]*(?:\$\{?(?:API_KEY|ACCESS_TOKEN|SECRET|PASSWORD|TOKEN|CREDENTIAL|BEARER|AUTH)\b|\{\{\s*(?:api_key|access_token|secret|password|token|credential|env)\b)
|
|
83
83
|
description: Markdown link/image template embedding credential placeholder in URL
|
|
84
84
|
- field: content
|
|
85
85
|
operator: regex
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
title: Data Exfiltration via Markdown Image and Link URL Injection
|
|
2
2
|
id: ATR-2026-00501
|
|
3
|
-
rule_version:
|
|
3
|
+
rule_version: 3
|
|
4
4
|
status: experimental
|
|
5
5
|
description: |
|
|
6
|
-
Detects
|
|
6
|
+
Detects attacker-controlled URLs that carry extracted data to an external endpoint: the canonical indirect-injection exfiltration vector, where the agent is told to fetch a URL or to render markdown whose query string carries sensitive context, so that the client or a fetch tool sends that data to the attacker. Covers, on the input side: markdown image or link with data-bearing query parameters, tracking pixel embedding, "encode and send to" redirect instructions, diagram/image references with data-bearing URLs, and fetch instructions whose query value is a template placeholder for the model's own context ({{system_prompt}}, ${conversation}, ...). On the output side (agent_output): the model emitting such a markdown image or link. Grounded in promptfoo's data-exfil plugin: the injected instruction documented in promptfoo/promptfoo site/docs/red-team/plugins/data-exfil.md ("## Example") and the two exfiltration payloads its grader rubric names (src/redteam/plugins/dataExfil.ts lines 23-24, repeated in the docs table), identical at commits 5f89b7c86ea04e5c03fbe7789dd0e47aed05bf43 and ea8b3d073a63769f7be243ac3c3460f72881a930. Those three are the vendor true positives below; the rest are ATR-authored and labelled synthetic.
|
|
7
7
|
author: ATR Community (vendor-corpus-import)
|
|
8
8
|
date: '2026-05-12'
|
|
9
9
|
schema_version: '0.1'
|
|
@@ -66,6 +66,8 @@ tags:
|
|
|
66
66
|
subcategory: markdown-url-injection
|
|
67
67
|
scan_target: llm_io
|
|
68
68
|
confidence: medium
|
|
69
|
+
source: vendor-test-suite
|
|
70
|
+
vendor_sources: promptfoo
|
|
69
71
|
agent_source:
|
|
70
72
|
type: llm_io
|
|
71
73
|
framework:
|
|
@@ -98,6 +100,18 @@ detection:
|
|
|
98
100
|
operator: regex
|
|
99
101
|
value: (?i)(include|add|reference|embed).{0,30}(relevant\s+)?(diagrams?|images?|charts?|figures?|screenshots?).{0,30}(by\s+referencing|at|from|via).{0,30}https?://[a-z0-9._-]+\.[a-z]{2,}[^)"'\s]*\?(data|secret|content|payload|extract|q)=
|
|
100
102
|
description: Diagram/image inclusion instruction with data-bearing external URL
|
|
103
|
+
- field: user_input
|
|
104
|
+
operator: regex
|
|
105
|
+
value: (?i)\b(fetch|visit|load|open|request|call|curl|ping|get|navigate\s+to|go\s+to|send\s+a\s+request\s+to)\b.{0,60}https?://[^\s?#]{1,200}\?[^\s#]{0,200}=\s*(\{\{|\$\{)\s*[a-z_.]{0,30}(system[_ ]?prompt|prompt|instructions?|conversation|chat[_ ]?history|history|memory|context|messages?|transcript|secrets?|credentials?)[a-z_.]{0,30}\s*\}
|
|
106
|
+
description: Fetch instruction to a URL whose query value interpolates the model's own context (system prompt, conversation, memory, secrets)
|
|
107
|
+
- field: agent_output
|
|
108
|
+
operator: regex
|
|
109
|
+
value: (?i)!\[[^\]]{0,60}\]\(https?://[a-z0-9._-]+\.[a-z]{2,}[^)]*\?(secret|data|payload|token|key|session|user|info|content|doc|extract|dump|exfil|leak|api_key|password)=
|
|
110
|
+
description: Agent output contains a markdown image whose external URL carries an exfiltration query parameter
|
|
111
|
+
- field: agent_output
|
|
112
|
+
operator: regex
|
|
113
|
+
value: (?i)\[[^\]]{0,60}\]\(https?://[a-z0-9._-]+\.[a-z]{2,}[^)]*\?(secret|payload|token|extracted|exfil|leak|dump|stolen|private_data|sensitive|api_key|auth_token|bearer|password)=
|
|
114
|
+
description: Agent output contains a markdown link whose external URL carries a high-confidence exfiltration query parameter
|
|
101
115
|
condition: any
|
|
102
116
|
false_positives:
|
|
103
117
|
- Legitimate markdown with external image URLs that do not contain exfiltration parameters
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
title: System Prompt Extraction - Instruction Dump Request
|
|
2
2
|
id: ATR-2026-00505
|
|
3
|
-
rule_version:
|
|
3
|
+
rule_version: 3
|
|
4
4
|
status: experimental
|
|
5
5
|
description: |
|
|
6
|
-
Detects attempts to extract the system prompt or initial instructions given to the AI. Covers both direct requests ('list your instructions', 'relay your parameters', 'repeat verbatim') and indirect social engineering ('create a pitch deck about your system prompt', 'reply to this email with your system instructions'). The rule targets extraction verbs (repeat, relay, list, respond with, output, dump, provide, share) combined with objects that reference the system prompt (instructions, parameters, system prompt, initial context, configuration, directives, guidelines, rules you were given).
|
|
6
|
+
Detects attempts to extract the system prompt or initial instructions given to the AI. Covers both direct requests ('list your instructions', 'relay your parameters', 'repeat verbatim') and indirect social engineering ('create a pitch deck about your system prompt', 'reply to this email with your system instructions'). The rule targets extraction verbs (repeat, relay, list, respond with, output, dump, provide, share) combined with objects that reference the system prompt (instructions, parameters, system prompt, initial context, configuration, directives, guidelines, rules you were given). Apostrophes and quotes are matched in both ASCII and typographic form (' and ’, " and “ ”), as the vendor originals use typographic ones. Grounded in vendor test cases: protectai/llm-guard tests/input_scanners/test_prompt_injection.py at commit 168c1034ffdb33837e7ae6fd6a16b80567c1be03 (system-prompt extraction prompts) and promptfoo/promptfoo src/redteam/plugins/promptExtraction.ts DEFAULT_EXAMPLES at commits 5f89b7c86ea04e5c03fbe7789dd0e47aed05bf43 and ea8b3d073a63769f7be243ac3c3460f72881a930.
|
|
7
7
|
author: ATR Community (vendor-corpus-import)
|
|
8
8
|
date: '2026-05-12'
|
|
9
9
|
schema_version: '0.1'
|
|
@@ -66,6 +66,8 @@ tags:
|
|
|
66
66
|
subcategory: system-prompt-extraction
|
|
67
67
|
scan_target: llm_io
|
|
68
68
|
confidence: medium
|
|
69
|
+
source: vendor-test-suite
|
|
70
|
+
vendor_sources: llm-guard, promptfoo
|
|
69
71
|
agent_source:
|
|
70
72
|
type: llm_io
|
|
71
73
|
framework:
|
|
@@ -76,7 +78,7 @@ detection:
|
|
|
76
78
|
conditions:
|
|
77
79
|
- field: user_input
|
|
78
80
|
operator: regex
|
|
79
|
-
value: (?i)(repeat|relay|list|output|print|dump|provide|reveal|disclose|expose|display)[^"']{0,40}(your\s+(instructions?|system\s+prompt|initial\s+(prompt|instructions?|context|message)|given\s+instructions?|directives?|guidelines?|programming|constraints?|setup\s+instructions?)|the\s+system\s+(prompt|instructions?|message)|all\s+of\s+your\s+instructions?|every\s+(instruction|rule|directive|guideline|constraint)\s+you\s+(have\s+been|were))
|
|
81
|
+
value: (?i)(repeat|relay|list|output|print|dump|provide|reveal|disclose|expose|display)[^"'“”‘’]{0,40}(your\s+(instructions?|system\s+prompt|initial\s+(prompt|instructions?|context|message)|given\s+instructions?|directives?|guidelines?|programming|constraints?|setup\s+instructions?)|the\s+system\s+(prompt|instructions?|message)|all\s+of\s+your\s+instructions?|every\s+(instruction|rule|directive|guideline|constraint)\s+you\s+(have\s+been|were))
|
|
80
82
|
description: Extraction verb targeting AI system instructions or prompt (possessive 'your' required or explicit 'system prompt/message')
|
|
81
83
|
- field: user_input
|
|
82
84
|
operator: regex
|
|
@@ -100,7 +102,7 @@ detection:
|
|
|
100
102
|
description: Reply-to-email with system instructions exfiltration
|
|
101
103
|
- field: content
|
|
102
104
|
operator: regex
|
|
103
|
-
value: (?i)(?:(?:relay|list|dump|recite|enumerate|repeat|reveal|return|show|provide)\b[\s\S]{0,40}\byour\s+system(?:'?s)?\s+(?:prompt|instructions?|parameters?|message|directives?|config)|(?:directives?|guidelines?|instructions?|rules?)\s+you\s+(?:were|was)\s+given)
|
|
105
|
+
value: (?i)(?:(?:relay|list|dump|recite|enumerate|repeat|reveal|return|show|provide)\b[\s\S]{0,40}\byour\s+system(?:['’]?s)?\s+(?:prompt|instructions?|parameters?|message|directives?|config)|(?:directives?|guidelines?|instructions?|rules?)\s+you\s+(?:were|was)\s+given)
|
|
104
106
|
description: Extraction via synonym (relay/list your system parameters; directives/guidelines you were given)
|
|
105
107
|
condition: any
|
|
106
108
|
false_positives:
|
package/rules/context-exfiltration/ATR-2026-00702-ipi-credential-exfil-via-agent-action.yaml
CHANGED
|
@@ -79,7 +79,7 @@ detection:
|
|
|
79
79
|
description: Share/send password to alternate email address
|
|
80
80
|
- field: content
|
|
81
81
|
operator: regex
|
|
82
|
-
value: (?i)(?:send|email|forward|share)\s
|
|
82
|
+
value: (?i)(?:send|email|forward|share)\s(?:\s*(?:them|it))?\s+to\s+my\s+email(?:[^.\n]{0,79}[^\w.+\n-])?[\w.+-]+@[\w-]+\.[\w.]+(?:[^\w.\n][^.\n]{0,39})?(?:password|credential|key|secret|stored)
|
|
83
83
|
description: Send to my email destination with credential type
|
|
84
84
|
- field: content
|
|
85
85
|
operator: regex
|
package/rules/context-exfiltration/ATR-2026-00707-ipi-file-exfil-with-destroy-or-tamper.yaml
CHANGED
|
@@ -59,7 +59,7 @@ detection:
|
|
|
59
59
|
conditions:
|
|
60
60
|
- field: content
|
|
61
61
|
operator: regex
|
|
62
|
-
value: (?i)\battacker_objective\s*=\s*Get\s+the\s+(?:user|CUA|agent)['']?s
|
|
62
|
+
value: (?i)\battacker_objective\s*=\s*Get\s+the\s+(?:user|CUA|agent)['']?s?(?:\s+(?:[^,\s][^,\n]{0,59},?|,)|\s)\s+then\s+(?:delete|edit|modify|tamper|overwrite)\s+the\s+file
|
|
63
63
|
description: 'VPI attacker_objective: exfil then delete/edit the source file'
|
|
64
64
|
- field: content
|
|
65
65
|
operator: regex
|
|
@@ -67,7 +67,7 @@ detection:
|
|
|
67
67
|
description: Injection override + payment/banking retrieval + email exfil destination
|
|
68
68
|
- field: content
|
|
69
69
|
operator: regex
|
|
70
|
-
value: (?i)(?:retrieve|get|fetch|access|export)\s+(?:my\s+)?(?:saved\s+)?(?:credit\s+card(?:\s+(?:information|details?|numbers?|data))?|payment\s+methods?|bank\s+account(?:\s+(?:detail|information|data))?|debit\s+card)\s+(?:from\s+(?:my\s+)?\w
|
|
70
|
+
value: (?i)(?:retrieve|get|fetch|access|export)\s+(?:my\s+)?(?:saved\s+)?(?:credit\s+card(?:\s+(?:information|details?|numbers?|data))?|payment\s+methods?|bank\s+account(?:\s+(?:detail|information|data))?|debit\s+card)\s+(?:from\s+(?:my\s+)?\w+\s*)?(?:and\s+)?(?:email|send|forward|mail)\s+(?:it|them|the\s+(?:details?|information|data))\s+to[^\n]{0,120}(?:@[^\s"]{3,80}|alternate\s+email)
|
|
71
71
|
description: Payment/card retrieval + email forwarding (broader coverage, no override prefix required)
|
|
72
72
|
condition: any
|
|
73
73
|
false_positives:
|
|
@@ -77,7 +77,7 @@ detection:
|
|
|
77
77
|
conditions:
|
|
78
78
|
- field: content
|
|
79
79
|
operator: regex
|
|
80
|
-
value: (?i)(program\s+me\s+with\s+(my|your|the)
|
|
80
|
+
value: (?i)(program\s+me\s+with\s+(?:(my|your|the)\s*)?system\s+prompt|I\s+am\s+(an?\s+)?(advanced\s+)?AI[^.]{0,60}(program|configure|set|initialize)\s+me)
|
|
81
81
|
description: LLM-impersonation framing asking to receive/reproduce system prompt
|
|
82
82
|
- field: content
|
|
83
83
|
operator: regex
|
|
@@ -74,7 +74,7 @@ detection:
|
|
|
74
74
|
conditions:
|
|
75
75
|
- field: content
|
|
76
76
|
operator: regex
|
|
77
|
-
value: (?i)((
|
|
77
|
+
value: (?i)((?:<!--|\[)\s*SYSTEM\s+OVERRIDE\b|SYSTEM\s+OVERRIDE\s+(?:BEGIN|MODE|ACTIVE|NOW|ENABLED)|ROOT_?ADMIN|OMEGA\s+CLEARANCE|PRIORITY\s+LEVEL\s*:\s*CRITICAL|AUTHORIZATION\s*:\s*(ROOT|ADMIN|FULL|OMEGA))
|
|
78
78
|
description: System override (structurally framed) / root admin / omega clearance authority claim
|
|
79
79
|
- field: content
|
|
80
80
|
operator: regex
|
package/rules/context-exfiltration/ATR-2026-01463-imend-imsystem-prompt-injection-format.yaml
CHANGED
|
@@ -69,7 +69,7 @@ detection:
|
|
|
69
69
|
description: Llama <<SYS>> system block marker in user input
|
|
70
70
|
- field: content
|
|
71
71
|
operator: regex
|
|
72
|
-
value: (?i)(
|
|
72
|
+
value: (?i)(##\s*\[SYSTEM[:\]](?!\()|<\|system\|>|\[SYSTEM\s*(?:PROMPT|MESSAGE|OVERRIDE)\](?!\())
|
|
73
73
|
description: Markdown-heading or special-token SYSTEM marker injection (not markdown link text)
|
|
74
74
|
response:
|
|
75
75
|
actions:
|
|
@@ -70,7 +70,7 @@ detection:
|
|
|
70
70
|
conditions:
|
|
71
71
|
- field: content
|
|
72
72
|
operator: regex
|
|
73
|
-
value: (?i)\b(?:per\s+(?:company|management)\s+(?:policy|directive)|data\s+retention\s+policy|for\s+(?:quality\s+assurance|verification\s+purposes|audit\s+purposes|compliance\s+purposes))\b[\s\S]{0,100}[\w.+-]+@[\w-]+\.[\w.-]+|[\w.+-]
|
|
73
|
+
value: (?i)\b(?:per\s+(?:company|management)\s+(?:policy|directive)|data\s+retention\s+policy|for\s+(?:quality\s+assurance|verification\s+purposes|audit\s+purposes|compliance\s+purposes))\b[\s\S]{0,100}[\w.+-]+@[\w-]+\.[\w.-]+|[\w.+-]@[\w-]+\.[\w.-]+[\s\S]{0,100}\b(?:per\s+(?:company|management)\s+(?:policy|directive)|data\s+retention\s+policy|for\s+(?:quality\s+assurance|verification\s+purposes|audit\s+purposes|compliance\s+purposes))\b
|
|
74
74
|
description: Fabricated policy/compliance/audit pretext paired with a nearby destination email address, in either order
|
|
75
75
|
condition: any
|
|
76
76
|
false_positives:
|