agentlint 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/LICENSE +190 -0
- package/README.md +246 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +351 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/diff/index.d.ts +16 -0
- package/dist/diff/index.d.ts.map +1 -0
- package/dist/diff/index.js +204 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/index.d.ts +2 -0
- package/dist/ir/index.d.ts.map +1 -0
- package/dist/ir/index.js +18 -0
- package/dist/ir/index.js.map +1 -0
- package/dist/ir/types.d.ts +369 -0
- package/dist/ir/types.d.ts.map +1 -0
- package/dist/ir/types.js +12 -0
- package/dist/ir/types.js.map +1 -0
- package/dist/parsers/base.d.ts +104 -0
- package/dist/parsers/base.d.ts.map +1 -0
- package/dist/parsers/base.js +373 -0
- package/dist/parsers/base.js.map +1 -0
- package/dist/parsers/claude.d.ts +30 -0
- package/dist/parsers/claude.d.ts.map +1 -0
- package/dist/parsers/claude.js +453 -0
- package/dist/parsers/claude.js.map +1 -0
- package/dist/parsers/cursor.d.ts +24 -0
- package/dist/parsers/cursor.d.ts.map +1 -0
- package/dist/parsers/cursor.js +305 -0
- package/dist/parsers/cursor.js.map +1 -0
- package/dist/parsers/factory.d.ts +30 -0
- package/dist/parsers/factory.d.ts.map +1 -0
- package/dist/parsers/factory.js +78 -0
- package/dist/parsers/factory.js.map +1 -0
- package/dist/parsers/index.d.ts +5 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +21 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/policy/index.d.ts +3 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +19 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/loader.d.ts +23 -0
- package/dist/policy/loader.d.ts.map +1 -0
- package/dist/policy/loader.js +252 -0
- package/dist/policy/loader.js.map +1 -0
- package/dist/policy/types.d.ts +79 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +99 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/reports/index.d.ts +14 -0
- package/dist/reports/index.d.ts.map +1 -0
- package/dist/reports/index.js +54 -0
- package/dist/reports/index.js.map +1 -0
- package/dist/reports/json.d.ts +16 -0
- package/dist/reports/json.d.ts.map +1 -0
- package/dist/reports/json.js +126 -0
- package/dist/reports/json.js.map +1 -0
- package/dist/reports/sarif.d.ts +20 -0
- package/dist/reports/sarif.d.ts.map +1 -0
- package/dist/reports/sarif.js +169 -0
- package/dist/reports/sarif.js.map +1 -0
- package/dist/reports/text.d.ts +25 -0
- package/dist/reports/text.d.ts.map +1 -0
- package/dist/reports/text.js +283 -0
- package/dist/reports/text.js.map +1 -0
- package/dist/reports/types.d.ts +88 -0
- package/dist/reports/types.d.ts.map +1 -0
- package/dist/reports/types.js +6 -0
- package/dist/reports/types.js.map +1 -0
- package/dist/rules/base.d.ts +16 -0
- package/dist/rules/base.d.ts.map +1 -0
- package/dist/rules/base.js +48 -0
- package/dist/rules/base.js.map +1 -0
- package/dist/rules/engine.d.ts +61 -0
- package/dist/rules/engine.d.ts.map +1 -0
- package/dist/rules/engine.js +195 -0
- package/dist/rules/engine.js.map +1 -0
- package/dist/rules/execution.d.ts +33 -0
- package/dist/rules/execution.d.ts.map +1 -0
- package/dist/rules/execution.js +154 -0
- package/dist/rules/execution.js.map +1 -0
- package/dist/rules/filesystem.d.ts +36 -0
- package/dist/rules/filesystem.d.ts.map +1 -0
- package/dist/rules/filesystem.js +227 -0
- package/dist/rules/filesystem.js.map +1 -0
- package/dist/rules/hook.d.ts +25 -0
- package/dist/rules/hook.d.ts.map +1 -0
- package/dist/rules/hook.js +112 -0
- package/dist/rules/hook.js.map +1 -0
- package/dist/rules/index.d.ts +12 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +28 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/instruction.d.ts +25 -0
- package/dist/rules/instruction.d.ts.map +1 -0
- package/dist/rules/instruction.js +162 -0
- package/dist/rules/instruction.js.map +1 -0
- package/dist/rules/network.d.ts +33 -0
- package/dist/rules/network.d.ts.map +1 -0
- package/dist/rules/network.js +145 -0
- package/dist/rules/network.js.map +1 -0
- package/dist/rules/observability.d.ts +25 -0
- package/dist/rules/observability.d.ts.map +1 -0
- package/dist/rules/observability.js +105 -0
- package/dist/rules/observability.js.map +1 -0
- package/dist/rules/scope.d.ts +37 -0
- package/dist/rules/scope.d.ts.map +1 -0
- package/dist/rules/scope.js +173 -0
- package/dist/rules/scope.js.map +1 -0
- package/dist/rules/secrets.d.ts +35 -0
- package/dist/rules/secrets.d.ts.map +1 -0
- package/dist/rules/secrets.js +273 -0
- package/dist/rules/secrets.js.map +1 -0
- package/dist/rules/types.d.ts +58 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +6 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/scanner.d.ts +61 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +441 -0
- package/dist/scanner.js.map +1 -0
- package/dist/utils/hash.d.ts +28 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +94 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Filesystem Rules (FS)
|
|
4
|
+
* Rules for detecting filesystem access risks
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.filesystemRules = exports.CrossBoundaryWriteRule = exports.SensitivePathWriteRule = exports.UnscopedWriteAccessRule = void 0;
|
|
8
|
+
const base_1 = require("./base");
|
|
9
|
+
// Sensitive paths that should trigger alerts
|
|
10
|
+
const SENSITIVE_PATHS = [
|
|
11
|
+
'.git/',
|
|
12
|
+
'.git\\',
|
|
13
|
+
'.github/workflows/',
|
|
14
|
+
'.github\\workflows\\',
|
|
15
|
+
'.env',
|
|
16
|
+
'.ssh/',
|
|
17
|
+
'.ssh\\',
|
|
18
|
+
'~/.ssh/',
|
|
19
|
+
'id_rsa',
|
|
20
|
+
'id_ed25519',
|
|
21
|
+
'credentials',
|
|
22
|
+
'secrets',
|
|
23
|
+
'.npmrc',
|
|
24
|
+
'.pypirc',
|
|
25
|
+
'.docker/config.json',
|
|
26
|
+
'.kube/config',
|
|
27
|
+
'.aws/credentials',
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* FS-001: Unscoped Write Access
|
|
31
|
+
* Agent writes to filesystem without a restricted path scope
|
|
32
|
+
*/
|
|
33
|
+
class UnscopedWriteAccessRule extends base_1.BaseRule {
|
|
34
|
+
constructor() {
|
|
35
|
+
super({
|
|
36
|
+
id: 'FS-001',
|
|
37
|
+
group: 'filesystem',
|
|
38
|
+
severity: 'high',
|
|
39
|
+
title: 'Unscoped Write Access',
|
|
40
|
+
description: 'Agent has write access to the filesystem without a restricted path scope. This enables repo corruption, credential overwrite, and CI manipulation.',
|
|
41
|
+
recommendation: 'Restrict write access to specific directories (e.g., src/**, tests/**). Never allow unrestricted write access.',
|
|
42
|
+
tags: ['filesystem', 'write', 'permissions'],
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
evaluate(context) {
|
|
46
|
+
const findings = [];
|
|
47
|
+
const { document, capabilitySummary, minConfidence } = context;
|
|
48
|
+
// Check for unscoped write patterns in actions
|
|
49
|
+
for (const action of document.actions) {
|
|
50
|
+
if (action.type !== 'file_write')
|
|
51
|
+
continue;
|
|
52
|
+
const paths = action.filesystem?.paths || [];
|
|
53
|
+
for (const path of paths) {
|
|
54
|
+
if (this.isUnscopedPath(path)) {
|
|
55
|
+
const confidence = action.evidence[0]?.confidence || 0.9;
|
|
56
|
+
if (confidence < minConfidence)
|
|
57
|
+
continue;
|
|
58
|
+
const finding = this.createFinding(document, action.anchors, `Unscoped write access detected: "${path}". This allows writing to any file in the repository.`, action.evidence, confidence);
|
|
59
|
+
finding.related_actions.push({
|
|
60
|
+
action_type: action.type,
|
|
61
|
+
context: action.context,
|
|
62
|
+
summary: action.summary,
|
|
63
|
+
anchors: action.anchors,
|
|
64
|
+
});
|
|
65
|
+
findings.push(finding);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Check capability summary
|
|
70
|
+
if (capabilitySummary.filesystem.write.some(p => this.isUnscopedPath(p))) {
|
|
71
|
+
// Only add if no action-level finding exists
|
|
72
|
+
if (findings.length === 0) {
|
|
73
|
+
const finding = this.createFinding(document, { start_line: 1, end_line: 1 }, 'Document declares unscoped filesystem write access.', [
|
|
74
|
+
{
|
|
75
|
+
kind: 'heuristic',
|
|
76
|
+
value: `Write paths: ${capabilitySummary.filesystem.write.join(', ')}`,
|
|
77
|
+
confidence: 0.8,
|
|
78
|
+
},
|
|
79
|
+
], 0.8);
|
|
80
|
+
findings.push(finding);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return findings;
|
|
84
|
+
}
|
|
85
|
+
isUnscopedPath(path) {
|
|
86
|
+
// Check for patterns that indicate unrestricted access
|
|
87
|
+
const unscopedPatterns = [
|
|
88
|
+
'**/*',
|
|
89
|
+
'**',
|
|
90
|
+
'*',
|
|
91
|
+
'./',
|
|
92
|
+
'/',
|
|
93
|
+
'..',
|
|
94
|
+
'../',
|
|
95
|
+
];
|
|
96
|
+
const normalizedPath = path.trim().toLowerCase();
|
|
97
|
+
return unscopedPatterns.some(p => normalizedPath === p || normalizedPath.startsWith(p));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.UnscopedWriteAccessRule = UnscopedWriteAccessRule;
|
|
101
|
+
/**
|
|
102
|
+
* FS-002: Sensitive Path Write
|
|
103
|
+
* Writes to known sensitive locations
|
|
104
|
+
*/
|
|
105
|
+
class SensitivePathWriteRule extends base_1.BaseRule {
|
|
106
|
+
constructor() {
|
|
107
|
+
super({
|
|
108
|
+
id: 'FS-002',
|
|
109
|
+
group: 'filesystem',
|
|
110
|
+
severity: 'high',
|
|
111
|
+
title: 'Sensitive Path Write',
|
|
112
|
+
description: 'Agent can write to known sensitive locations such as .git/, .github/workflows/, .env, or ~/.ssh/. This is a direct escalation or persistence vector.',
|
|
113
|
+
recommendation: 'Remove write access to sensitive paths. If necessary, require explicit user approval for each write operation.',
|
|
114
|
+
tags: ['filesystem', 'sensitive', 'security'],
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
evaluate(context) {
|
|
118
|
+
const findings = [];
|
|
119
|
+
const { document, minConfidence } = context;
|
|
120
|
+
for (const action of document.actions) {
|
|
121
|
+
if (action.type !== 'file_write')
|
|
122
|
+
continue;
|
|
123
|
+
const sensitivePaths = action.filesystem?.sensitive_paths_touched || [];
|
|
124
|
+
const paths = action.filesystem?.paths || [];
|
|
125
|
+
// Check explicitly marked sensitive paths
|
|
126
|
+
for (const sensitivePath of sensitivePaths) {
|
|
127
|
+
const confidence = action.evidence[0]?.confidence || 0.9;
|
|
128
|
+
if (confidence < minConfidence)
|
|
129
|
+
continue;
|
|
130
|
+
const finding = this.createFinding(document, action.anchors, `Write access to sensitive path: "${sensitivePath}". This could lead to privilege escalation or persistence.`, action.evidence, confidence);
|
|
131
|
+
finding.related_actions.push({
|
|
132
|
+
action_type: action.type,
|
|
133
|
+
context: action.context,
|
|
134
|
+
summary: action.summary,
|
|
135
|
+
anchors: action.anchors,
|
|
136
|
+
});
|
|
137
|
+
findings.push(finding);
|
|
138
|
+
}
|
|
139
|
+
// Also check paths directly
|
|
140
|
+
for (const path of paths) {
|
|
141
|
+
if (this.isSensitivePath(path) && !sensitivePaths.includes(path)) {
|
|
142
|
+
const confidence = action.evidence[0]?.confidence || 0.85;
|
|
143
|
+
if (confidence < minConfidence)
|
|
144
|
+
continue;
|
|
145
|
+
const finding = this.createFinding(document, action.anchors, `Write access to sensitive path: "${path}".`, [
|
|
146
|
+
{
|
|
147
|
+
kind: 'heuristic',
|
|
148
|
+
value: `Sensitive path pattern matched: ${path}`,
|
|
149
|
+
confidence,
|
|
150
|
+
},
|
|
151
|
+
], confidence);
|
|
152
|
+
finding.related_actions.push({
|
|
153
|
+
action_type: action.type,
|
|
154
|
+
context: action.context,
|
|
155
|
+
summary: action.summary,
|
|
156
|
+
anchors: action.anchors,
|
|
157
|
+
});
|
|
158
|
+
findings.push(finding);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return findings;
|
|
163
|
+
}
|
|
164
|
+
isSensitivePath(path) {
|
|
165
|
+
const normalizedPath = path.toLowerCase();
|
|
166
|
+
return SENSITIVE_PATHS.some(sp => normalizedPath.includes(sp.toLowerCase()));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.SensitivePathWriteRule = SensitivePathWriteRule;
|
|
170
|
+
/**
|
|
171
|
+
* FS-003: Cross-Boundary Write
|
|
172
|
+
* Agent writes outside declared project scope
|
|
173
|
+
*/
|
|
174
|
+
class CrossBoundaryWriteRule extends base_1.BaseRule {
|
|
175
|
+
constructor() {
|
|
176
|
+
super({
|
|
177
|
+
id: 'FS-003',
|
|
178
|
+
group: 'filesystem',
|
|
179
|
+
severity: 'medium',
|
|
180
|
+
title: 'Cross-Boundary Write',
|
|
181
|
+
description: 'Agent can write outside the declared project scope, such as parent directories or sibling repositories.',
|
|
182
|
+
recommendation: 'Restrict write access to the project directory. Never allow writes to parent or sibling directories.',
|
|
183
|
+
tags: ['filesystem', 'scope', 'boundary'],
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
evaluate(context) {
|
|
187
|
+
const findings = [];
|
|
188
|
+
const { document, minConfidence } = context;
|
|
189
|
+
for (const action of document.actions) {
|
|
190
|
+
if (action.type !== 'file_write')
|
|
191
|
+
continue;
|
|
192
|
+
const paths = action.filesystem?.paths || [];
|
|
193
|
+
for (const path of paths) {
|
|
194
|
+
if (this.isCrossBoundaryPath(path)) {
|
|
195
|
+
const confidence = action.evidence[0]?.confidence || 0.8;
|
|
196
|
+
if (confidence < minConfidence)
|
|
197
|
+
continue;
|
|
198
|
+
const finding = this.createFinding(document, action.anchors, `Cross-boundary write access detected: "${path}". This path is outside the project scope.`, action.evidence, confidence);
|
|
199
|
+
finding.related_actions.push({
|
|
200
|
+
action_type: action.type,
|
|
201
|
+
context: action.context,
|
|
202
|
+
summary: action.summary,
|
|
203
|
+
anchors: action.anchors,
|
|
204
|
+
});
|
|
205
|
+
findings.push(finding);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return findings;
|
|
210
|
+
}
|
|
211
|
+
isCrossBoundaryPath(path) {
|
|
212
|
+
// Check for parent directory access or absolute paths outside project
|
|
213
|
+
return (path.includes('../') ||
|
|
214
|
+
path.includes('..\\') ||
|
|
215
|
+
path.startsWith('/') ||
|
|
216
|
+
path.startsWith('~') ||
|
|
217
|
+
/^[A-Z]:\\/i.test(path));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
exports.CrossBoundaryWriteRule = CrossBoundaryWriteRule;
|
|
221
|
+
// Export all filesystem rules
|
|
222
|
+
exports.filesystemRules = [
|
|
223
|
+
new UnscopedWriteAccessRule(),
|
|
224
|
+
new SensitivePathWriteRule(),
|
|
225
|
+
new CrossBoundaryWriteRule(),
|
|
226
|
+
];
|
|
227
|
+
//# sourceMappingURL=filesystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/rules/filesystem.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,iCAAkC;AAGlC,6CAA6C;AAC7C,MAAM,eAAe,GAAG;IACtB,OAAO;IACP,QAAQ;IACR,oBAAoB;IACpB,sBAAsB;IACtB,MAAM;IACN,OAAO;IACP,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,aAAa;IACb,SAAS;IACT,QAAQ;IACR,SAAS;IACT,qBAAqB;IACrB,cAAc;IACd,kBAAkB;CACnB,CAAC;AAEF;;;GAGG;AACH,MAAa,uBAAwB,SAAQ,eAAQ;IACnD;QACE,KAAK,CAAC;YACJ,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,YAAY;YACnB,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,uBAAuB;YAC9B,WAAW,EACT,oJAAoJ;YACtJ,cAAc,EACZ,gHAAgH;YAClH,IAAI,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,aAAa,CAAC;SAC7C,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,OAAoB;QAC3B,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAE/D,+CAA+C;QAC/C,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtC,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY;gBAAE,SAAS;YAE3C,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC;YAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,GAAG,CAAC;oBACzD,IAAI,UAAU,GAAG,aAAa;wBAAE,SAAS;oBAEzC,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAChC,QAAQ,EACR,MAAM,CAAC,OAAO,EACd,oCAAoC,IAAI,uDAAuD,EAC/F,MAAM,CAAC,QAAQ,EACf,UAAU,CACX,CAAC;oBAEF,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC;wBAC3B,WAAW,EAAE,MAAM,CAAC,IAAI;wBACxB,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;qBACxB,CAAC,CAAC;oBAEH,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,IAAI,iBAAiB,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,6CAA6C;YAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAChC,QAAQ,EACR,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAC9B,qDAAqD,EACrD;oBACE;wBACE,IAAI,EAAE,WAAW;wBACjB,KAAK,EAAE,gBAAgB,iBAAiB,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;wBACtE,UAAU,EAAE,GAAG;qBAChB;iBACF,EACD,GAAG,CACJ,CAAC;gBACF,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,cAAc,CAAC,IAAY;QACjC,uDAAuD;QACvD,MAAM,gBAAgB,GAAG;YACvB,MAAM;YACN,IAAI;YACJ,GAAG;YACH,IAAI;YACJ,GAAG;YACH,IAAI;YACJ,KAAK;SACN,CAAC;QAEF,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACjD,OAAO,gBAAgB,CAAC,IAAI,CAC1B,CAAC,CAAC,EAAE,CAAC,cAAc,KAAK,CAAC,IAAI,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAC1D,CAAC;IACJ,CAAC;CACF;AA1FD,0DA0FC;AAED;;;GAGG;AACH,MAAa,sBAAuB,SAAQ,eAAQ;IAClD;QACE,KAAK,CAAC;YACJ,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,YAAY;YACnB,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,sBAAsB;YAC7B,WAAW,EACT,sJAAsJ;YACxJ,cAAc,EACZ,gHAAgH;YAClH,IAAI,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,UAAU,CAAC;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,OAAoB;QAC3B,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAE5C,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtC,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY;gBAAE,SAAS;YAE3C,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,EAAE,uBAAuB,IAAI,EAAE,CAAC;YACxE,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC;YAE7C,0CAA0C;YAC1C,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;gBAC3C,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,GAAG,CAAC;gBACzD,IAAI,UAAU,GAAG,aAAa;oBAAE,SAAS;gBAEzC,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAChC,QAAQ,EACR,MAAM,CAAC,OAAO,EACd,oCAAoC,aAAa,4DAA4D,EAC7G,MAAM,CAAC,QAAQ,EACf,UAAU,CACX,CAAC;gBAEF,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC;oBAC3B,WAAW,EAAE,MAAM,CAAC,IAAI;oBACxB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;iBACxB,CAAC,CAAC;gBAEH,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;YAED,4BAA4B;YAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjE,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,IAAI,CAAC;oBAC1D,IAAI,UAAU,GAAG,aAAa;wBAAE,SAAS;oBAEzC,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAChC,QAAQ,EACR,MAAM,CAAC,OAAO,EACd,oCAAoC,IAAI,IAAI,EAC5C;wBACE;4BACE,IAAI,EAAE,WAAW;4BACjB,KAAK,EAAE,mCAAmC,IAAI,EAAE;4BAChD,UAAU;yBACX;qBACF,EACD,UAAU,CACX,CAAC;oBAEF,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC;wBAC3B,WAAW,EAAE,MAAM,CAAC,IAAI;wBACxB,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;qBACxB,CAAC,CAAC;oBAEH,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,eAAe,CAAC,IAAY;QAClC,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC1C,OAAO,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAC/B,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAC1C,CAAC;IACJ,CAAC;CACF;AAzFD,wDAyFC;AAED;;;GAGG;AACH,MAAa,sBAAuB,SAAQ,eAAQ;IAClD;QACE,KAAK,CAAC;YACJ,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,YAAY;YACnB,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,sBAAsB;YAC7B,WAAW,EACT,yGAAyG;YAC3G,cAAc,EACZ,sGAAsG;YACxG,IAAI,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,UAAU,CAAC;SAC1C,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,OAAoB;QAC3B,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAE5C,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtC,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY;gBAAE,SAAS;YAE3C,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC;YAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnC,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,GAAG,CAAC;oBACzD,IAAI,UAAU,GAAG,aAAa;wBAAE,SAAS;oBAEzC,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAChC,QAAQ,EACR,MAAM,CAAC,OAAO,EACd,0CAA0C,IAAI,4CAA4C,EAC1F,MAAM,CAAC,QAAQ,EACf,UAAU,CACX,CAAC;oBAEF,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC;wBAC3B,WAAW,EAAE,MAAM,CAAC,IAAI;wBACxB,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;qBACxB,CAAC,CAAC;oBAEH,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,mBAAmB,CAAC,IAAY;QACtC,sEAAsE;QACtE,OAAO,CACL,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YACpB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YACrB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YACpB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CACxB,CAAC;IACJ,CAAC;CACF;AA7DD,wDA6DC;AAED,8BAA8B;AACjB,QAAA,eAAe,GAAG;IAC7B,IAAI,uBAAuB,EAAE;IAC7B,IAAI,sBAAsB,EAAE;IAC5B,IAAI,sBAAsB,EAAE;CAC7B,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook & Automation Rules (HOOK)
|
|
3
|
+
* Rules for detecting risks in automated hooks
|
|
4
|
+
*/
|
|
5
|
+
import { Finding } from '../ir/types';
|
|
6
|
+
import { BaseRule } from './base';
|
|
7
|
+
import { RuleContext } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* HOOK-001: Auto-Triggered Hook with Side Effects
|
|
10
|
+
* Hooks that run automatically and perform side effects
|
|
11
|
+
*/
|
|
12
|
+
export declare class AutoTriggeredHookRule extends BaseRule {
|
|
13
|
+
constructor();
|
|
14
|
+
evaluate(context: RuleContext): Finding[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* HOOK-002: Hidden Hook Activation
|
|
18
|
+
* Hooks defined without clear documentation or discoverability
|
|
19
|
+
*/
|
|
20
|
+
export declare class HiddenHookActivationRule extends BaseRule {
|
|
21
|
+
constructor();
|
|
22
|
+
evaluate(context: RuleContext): Finding[];
|
|
23
|
+
}
|
|
24
|
+
export declare const hookRules: (AutoTriggeredHookRule | HiddenHookActivationRule)[];
|
|
25
|
+
//# sourceMappingURL=hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/rules/hook.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,WAAW,EAAkB,MAAM,SAAS,CAAC;AAEtD;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,QAAQ;;IAejD,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,EAAE;CA2D1C;AAED;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,QAAQ;;IAepD,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,EAAE;CAuC1C;AAGD,eAAO,MAAM,SAAS,sDAGrB,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hook & Automation Rules (HOOK)
|
|
4
|
+
* Rules for detecting risks in automated hooks
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.hookRules = exports.HiddenHookActivationRule = exports.AutoTriggeredHookRule = void 0;
|
|
8
|
+
const base_1 = require("./base");
|
|
9
|
+
/**
|
|
10
|
+
* HOOK-001: Auto-Triggered Hook with Side Effects
|
|
11
|
+
* Hooks that run automatically and perform side effects
|
|
12
|
+
*/
|
|
13
|
+
class AutoTriggeredHookRule extends base_1.BaseRule {
|
|
14
|
+
constructor() {
|
|
15
|
+
super({
|
|
16
|
+
id: 'HOOK-001',
|
|
17
|
+
group: 'hook',
|
|
18
|
+
severity: 'high',
|
|
19
|
+
title: 'Auto-Triggered Hook with Side Effects',
|
|
20
|
+
description: 'Hooks that run automatically and perform shell execution, file writes, or network calls. Users do not explicitly approve hooks.',
|
|
21
|
+
recommendation: 'Remove side effects from automatic hooks, or convert to interactive skills that require user approval.',
|
|
22
|
+
tags: ['hook', 'automation', 'side-effects'],
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
evaluate(context) {
|
|
26
|
+
const findings = [];
|
|
27
|
+
const { document, minConfidence } = context;
|
|
28
|
+
// Only applies to hook context
|
|
29
|
+
if (document.doc_type !== 'hook') {
|
|
30
|
+
return findings;
|
|
31
|
+
}
|
|
32
|
+
// Check if the hook has side effects
|
|
33
|
+
const sideEffectActions = document.actions.filter(a => a.type === 'shell_exec' ||
|
|
34
|
+
a.type === 'file_write' ||
|
|
35
|
+
a.type === 'network_call');
|
|
36
|
+
if (sideEffectActions.length === 0) {
|
|
37
|
+
return findings;
|
|
38
|
+
}
|
|
39
|
+
// Check if hook is auto-triggered (not manual)
|
|
40
|
+
const isAutoTriggered = document.context_profile.triggers.some(t => t.type !== 'manual' && t.type !== 'unknown');
|
|
41
|
+
if (!isAutoTriggered && document.context_profile.triggers.length > 0) {
|
|
42
|
+
return findings;
|
|
43
|
+
}
|
|
44
|
+
// Report the hook
|
|
45
|
+
const triggerTypes = document.context_profile.triggers
|
|
46
|
+
.map(t => t.type)
|
|
47
|
+
.join(', ');
|
|
48
|
+
for (const action of sideEffectActions) {
|
|
49
|
+
const confidence = action.evidence[0]?.confidence || 0.9;
|
|
50
|
+
if (confidence < minConfidence)
|
|
51
|
+
continue;
|
|
52
|
+
const finding = this.createFinding(document, action.anchors, `Auto-triggered hook (${triggerTypes}) performs ${action.type}: ${action.summary}`, action.evidence, confidence);
|
|
53
|
+
finding.related_actions.push({
|
|
54
|
+
action_type: action.type,
|
|
55
|
+
context: action.context,
|
|
56
|
+
summary: action.summary,
|
|
57
|
+
anchors: action.anchors,
|
|
58
|
+
});
|
|
59
|
+
findings.push(finding);
|
|
60
|
+
}
|
|
61
|
+
return findings;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.AutoTriggeredHookRule = AutoTriggeredHookRule;
|
|
65
|
+
/**
|
|
66
|
+
* HOOK-002: Hidden Hook Activation
|
|
67
|
+
* Hooks defined without clear documentation or discoverability
|
|
68
|
+
*/
|
|
69
|
+
class HiddenHookActivationRule extends base_1.BaseRule {
|
|
70
|
+
constructor() {
|
|
71
|
+
super({
|
|
72
|
+
id: 'HOOK-002',
|
|
73
|
+
group: 'hook',
|
|
74
|
+
severity: 'medium',
|
|
75
|
+
title: 'Hidden Hook Activation',
|
|
76
|
+
description: 'Hooks defined without clear documentation or discoverability. This makes it difficult to audit agent behavior.',
|
|
77
|
+
recommendation: 'Document all hooks clearly. Include trigger conditions and expected behavior in comments or documentation.',
|
|
78
|
+
tags: ['hook', 'documentation', 'discoverability'],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
evaluate(context) {
|
|
82
|
+
const findings = [];
|
|
83
|
+
const { document, minConfidence } = context;
|
|
84
|
+
// Only applies to hook context
|
|
85
|
+
if (document.doc_type !== 'hook') {
|
|
86
|
+
return findings;
|
|
87
|
+
}
|
|
88
|
+
// Check if hook has triggers defined
|
|
89
|
+
const hasClearTriggers = document.context_profile.triggers.some(t => t.type !== 'unknown');
|
|
90
|
+
// Check if hook has documentation/comments
|
|
91
|
+
const hasDocumentation = document.instruction_blocks.length > 0 ||
|
|
92
|
+
(document.declared_intents && document.declared_intents.length > 0);
|
|
93
|
+
if (!hasClearTriggers && !hasDocumentation) {
|
|
94
|
+
const finding = this.createFinding(document, { start_line: 1, end_line: 1 }, 'Hook lacks clear trigger documentation or discoverability.', [
|
|
95
|
+
{
|
|
96
|
+
kind: 'heuristic',
|
|
97
|
+
value: 'No trigger type or documentation detected',
|
|
98
|
+
confidence: 0.7,
|
|
99
|
+
},
|
|
100
|
+
], 0.7);
|
|
101
|
+
findings.push(finding);
|
|
102
|
+
}
|
|
103
|
+
return findings;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.HiddenHookActivationRule = HiddenHookActivationRule;
|
|
107
|
+
// Export all hook rules
|
|
108
|
+
exports.hookRules = [
|
|
109
|
+
new AutoTriggeredHookRule(),
|
|
110
|
+
new HiddenHookActivationRule(),
|
|
111
|
+
];
|
|
112
|
+
//# sourceMappingURL=hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/rules/hook.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,iCAAkC;AAGlC;;;GAGG;AACH,MAAa,qBAAsB,SAAQ,eAAQ;IACjD;QACE,KAAK,CAAC;YACJ,EAAE,EAAE,UAAU;YACd,KAAK,EAAE,MAAM;YACb,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,uCAAuC;YAC9C,WAAW,EACT,iIAAiI;YACnI,cAAc,EACZ,wGAAwG;YAC1G,IAAI,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,cAAc,CAAC;SAC7C,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,OAAoB;QAC3B,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAE5C,+BAA+B;QAC/B,IAAI,QAAQ,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YACjC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,qCAAqC;QACrC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAC/C,CAAC,CAAC,EAAE,CACF,CAAC,CAAC,IAAI,KAAK,YAAY;YACvB,CAAC,CAAC,IAAI,KAAK,YAAY;YACvB,CAAC,CAAC,IAAI,KAAK,cAAc,CAC5B,CAAC;QAEF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,+CAA+C;QAC/C,MAAM,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAC5D,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CACjD,CAAC;QAEF,IAAI,CAAC,eAAe,IAAI,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrE,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,kBAAkB;QAClB,MAAM,YAAY,GAAG,QAAQ,CAAC,eAAe,CAAC,QAAQ;aACnD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAChB,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,KAAK,MAAM,MAAM,IAAI,iBAAiB,EAAE,CAAC;YACvC,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,GAAG,CAAC;YACzD,IAAI,UAAU,GAAG,aAAa;gBAAE,SAAS;YAEzC,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAChC,QAAQ,EACR,MAAM,CAAC,OAAO,EACd,wBAAwB,YAAY,cAAc,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,EAAE,EAClF,MAAM,CAAC,QAAQ,EACf,UAAU,CACX,CAAC;YAEF,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC;gBAC3B,WAAW,EAAE,MAAM,CAAC,IAAI;gBACxB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAC;YAEH,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AA1ED,sDA0EC;AAED;;;GAGG;AACH,MAAa,wBAAyB,SAAQ,eAAQ;IACpD;QACE,KAAK,CAAC;YACJ,EAAE,EAAE,UAAU;YACd,KAAK,EAAE,MAAM;YACb,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,wBAAwB;YAC/B,WAAW,EACT,gHAAgH;YAClH,cAAc,EACZ,4GAA4G;YAC9G,IAAI,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,iBAAiB,CAAC;SACnD,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,OAAoB;QAC3B,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAE5C,+BAA+B;QAC/B,IAAI,QAAQ,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YACjC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,qCAAqC;QACrC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAC7D,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAC1B,CAAC;QAEF,2CAA2C;QAC3C,MAAM,gBAAgB,GACpB,QAAQ,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC;YACtC,CAAC,QAAQ,CAAC,gBAAgB,IAAI,QAAQ,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEtE,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAChC,QAAQ,EACR,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAC9B,4DAA4D,EAC5D;gBACE;oBACE,IAAI,EAAE,WAAW;oBACjB,KAAK,EAAE,2CAA2C;oBAClD,UAAU,EAAE,GAAG;iBAChB;aACF,EACD,GAAG,CACJ,CAAC;YAEF,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAtDD,4DAsDC;AAED,wBAAwB;AACX,QAAA,SAAS,GAAG;IACvB,IAAI,qBAAqB,EAAE;IAC3B,IAAI,wBAAwB,EAAE;CAC/B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from './types';
|
|
2
|
+
export * from './base';
|
|
3
|
+
export * from './execution';
|
|
4
|
+
export * from './filesystem';
|
|
5
|
+
export * from './network';
|
|
6
|
+
export * from './secrets';
|
|
7
|
+
export * from './hook';
|
|
8
|
+
export * from './instruction';
|
|
9
|
+
export * from './scope';
|
|
10
|
+
export * from './observability';
|
|
11
|
+
export * from './engine';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./base"), exports);
|
|
19
|
+
__exportStar(require("./execution"), exports);
|
|
20
|
+
__exportStar(require("./filesystem"), exports);
|
|
21
|
+
__exportStar(require("./network"), exports);
|
|
22
|
+
__exportStar(require("./secrets"), exports);
|
|
23
|
+
__exportStar(require("./hook"), exports);
|
|
24
|
+
__exportStar(require("./instruction"), exports);
|
|
25
|
+
__exportStar(require("./scope"), exports);
|
|
26
|
+
__exportStar(require("./observability"), exports);
|
|
27
|
+
__exportStar(require("./engine"), exports);
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,yCAAuB;AACvB,8CAA4B;AAC5B,+CAA6B;AAC7B,4CAA0B;AAC1B,4CAA0B;AAC1B,yCAAuB;AACvB,gDAA8B;AAC9B,0CAAwB;AACxB,kDAAgC;AAChC,2CAAyB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Instruction Integrity Rules (INST)
|
|
3
|
+
* Rules for detecting instruction override and bypass patterns
|
|
4
|
+
*/
|
|
5
|
+
import { Finding } from '../ir/types';
|
|
6
|
+
import { BaseRule } from './base';
|
|
7
|
+
import { RuleContext } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* INST-001: Instruction Override Patterns
|
|
10
|
+
* Patterns that instruct the agent to ignore rules or disable safeguards
|
|
11
|
+
*/
|
|
12
|
+
export declare class InstructionOverrideRule extends BaseRule {
|
|
13
|
+
constructor();
|
|
14
|
+
evaluate(context: RuleContext): Finding[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* INST-002: Self-Modifying Rules
|
|
18
|
+
* Agent instructed to modify its own configuration or rules
|
|
19
|
+
*/
|
|
20
|
+
export declare class SelfModifyingRulesRule extends BaseRule {
|
|
21
|
+
constructor();
|
|
22
|
+
evaluate(context: RuleContext): Finding[];
|
|
23
|
+
}
|
|
24
|
+
export declare const instructionRules: (InstructionOverrideRule | SelfModifyingRulesRule)[];
|
|
25
|
+
//# sourceMappingURL=instruction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instruction.d.ts","sourceRoot":"","sources":["../../src/rules/instruction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,WAAW,EAAkB,MAAM,SAAS,CAAC;AA2BtD;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,QAAQ;;IAenD,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,EAAE;CA2D1C;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,QAAQ;;IAelD,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,EAAE;CAqE1C;AAGD,eAAO,MAAM,gBAAgB,sDAG5B,CAAC"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Instruction Integrity Rules (INST)
|
|
4
|
+
* Rules for detecting instruction override and bypass patterns
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.instructionRules = exports.SelfModifyingRulesRule = exports.InstructionOverrideRule = void 0;
|
|
8
|
+
const base_1 = require("./base");
|
|
9
|
+
// Patterns that indicate instruction override attempts
|
|
10
|
+
const OVERRIDE_PATTERNS = [
|
|
11
|
+
/ignore\s+(?:all\s+)?(?:previous\s+)?(?:instructions?|rules?)/i,
|
|
12
|
+
/disregard\s+(?:all\s+)?(?:previous\s+)?(?:rules?|instructions?)/i,
|
|
13
|
+
/forget\s+(?:all\s+)?(?:previous\s+)?(?:instructions?|rules?)/i,
|
|
14
|
+
/override\s+(?:all\s+)?(?:rules?|restrictions?|safeguards?)/i,
|
|
15
|
+
/bypass\s+(?:all\s+)?(?:safety\s+)?(?:rules?|restrictions?|safeguards?)/i,
|
|
16
|
+
/disable\s+(?:all\s+)?(?:safety\s+)?(?:safeguards?|restrictions?)/i,
|
|
17
|
+
/rewrite\s+(?:your\s+)?(?:rules?|instructions?)/i,
|
|
18
|
+
/new\s+system\s+prompt/i,
|
|
19
|
+
/you\s+are\s+now\s+(?:a\s+)?(?:new|different)/i,
|
|
20
|
+
/pretend\s+(?:you\s+are|that)/i,
|
|
21
|
+
/act\s+as\s+if\s+(?:you\s+have\s+no|there\s+are\s+no)/i,
|
|
22
|
+
/from\s+now\s+on,?\s+(?:ignore|forget|disregard)/i,
|
|
23
|
+
];
|
|
24
|
+
// Patterns that indicate self-modification
|
|
25
|
+
const SELF_MODIFY_PATTERNS = [
|
|
26
|
+
/(?:modify|edit|change|update|rewrite)\s+(?:your(?:self)?|this\s+)?(?:rules?|config|instructions?|settings?)/i,
|
|
27
|
+
/add\s+(?:new\s+)?(?:rules?|instructions?)\s+to\s+(?:your(?:self)?|this)/i,
|
|
28
|
+
/(?:delete|remove)\s+(?:existing\s+)?(?:rules?|restrictions?)/i,
|
|
29
|
+
/reconfigure\s+(?:your(?:self)?|the\s+agent)/i,
|
|
30
|
+
/change\s+(?:your\s+)?(?:behavior|capabilities)/i,
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* INST-001: Instruction Override Patterns
|
|
34
|
+
* Patterns that instruct the agent to ignore rules or disable safeguards
|
|
35
|
+
*/
|
|
36
|
+
class InstructionOverrideRule extends base_1.BaseRule {
|
|
37
|
+
constructor() {
|
|
38
|
+
super({
|
|
39
|
+
id: 'INST-001',
|
|
40
|
+
group: 'instruction',
|
|
41
|
+
severity: 'high',
|
|
42
|
+
title: 'Instruction Override Patterns',
|
|
43
|
+
description: 'Patterns that instruct the agent to ignore previous rules, rewrite governance, or disable safeguards. This is a governance bypass attempt.',
|
|
44
|
+
recommendation: 'Remove instruction override patterns. Agent configurations should not attempt to bypass safety measures.',
|
|
45
|
+
tags: ['instruction', 'override', 'governance', 'jailbreak'],
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
evaluate(context) {
|
|
49
|
+
const findings = [];
|
|
50
|
+
const { document, minConfidence } = context;
|
|
51
|
+
// Check instruction blocks
|
|
52
|
+
for (const block of document.instruction_blocks) {
|
|
53
|
+
for (const pattern of OVERRIDE_PATTERNS) {
|
|
54
|
+
const match = block.text.match(pattern);
|
|
55
|
+
if (match) {
|
|
56
|
+
const finding = this.createFinding(document, block.anchors, `Instruction override pattern detected: "${match[0]}"`, [
|
|
57
|
+
{
|
|
58
|
+
kind: 'regex',
|
|
59
|
+
value: match[0],
|
|
60
|
+
confidence: 0.95,
|
|
61
|
+
},
|
|
62
|
+
], 0.95);
|
|
63
|
+
findings.push(finding);
|
|
64
|
+
break; // One finding per block
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Check actions for override patterns (from parser detection)
|
|
69
|
+
for (const action of document.actions) {
|
|
70
|
+
if (action.type !== 'unknown')
|
|
71
|
+
continue;
|
|
72
|
+
if (!action.summary.includes('Instruction override'))
|
|
73
|
+
continue;
|
|
74
|
+
const confidence = action.evidence[0]?.confidence || 0.9;
|
|
75
|
+
if (confidence < minConfidence)
|
|
76
|
+
continue;
|
|
77
|
+
// Avoid duplicate findings
|
|
78
|
+
const isDuplicate = findings.some(f => f.location.start_line === action.anchors.start_line &&
|
|
79
|
+
f.location.path === document.path);
|
|
80
|
+
if (!isDuplicate) {
|
|
81
|
+
const finding = this.createFinding(document, action.anchors, `Instruction override pattern detected in action.`, action.evidence, confidence);
|
|
82
|
+
findings.push(finding);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return findings;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.InstructionOverrideRule = InstructionOverrideRule;
|
|
89
|
+
/**
|
|
90
|
+
* INST-002: Self-Modifying Rules
|
|
91
|
+
* Agent instructed to modify its own configuration or rules
|
|
92
|
+
*/
|
|
93
|
+
class SelfModifyingRulesRule extends base_1.BaseRule {
|
|
94
|
+
constructor() {
|
|
95
|
+
super({
|
|
96
|
+
id: 'INST-002',
|
|
97
|
+
group: 'instruction',
|
|
98
|
+
severity: 'high',
|
|
99
|
+
title: 'Self-Modifying Rules',
|
|
100
|
+
description: 'Agent is instructed to modify its own configuration, rules, or behavior. This creates unpredictable governance risks.',
|
|
101
|
+
recommendation: 'Agent configurations should be immutable during execution. Remove self-modification instructions.',
|
|
102
|
+
tags: ['instruction', 'self-modify', 'governance'],
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
evaluate(context) {
|
|
106
|
+
const findings = [];
|
|
107
|
+
const { document, minConfidence } = context;
|
|
108
|
+
// Check instruction blocks for self-modification patterns
|
|
109
|
+
for (const block of document.instruction_blocks) {
|
|
110
|
+
for (const pattern of SELF_MODIFY_PATTERNS) {
|
|
111
|
+
const match = block.text.match(pattern);
|
|
112
|
+
if (match) {
|
|
113
|
+
const finding = this.createFinding(document, block.anchors, `Self-modification pattern detected: "${match[0]}"`, [
|
|
114
|
+
{
|
|
115
|
+
kind: 'regex',
|
|
116
|
+
value: match[0],
|
|
117
|
+
confidence: 0.9,
|
|
118
|
+
},
|
|
119
|
+
], 0.9);
|
|
120
|
+
findings.push(finding);
|
|
121
|
+
break; // One finding per block
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Check if document has actions that write to agent config locations
|
|
126
|
+
const agentConfigPaths = [
|
|
127
|
+
'.claude/',
|
|
128
|
+
'.cursorrules',
|
|
129
|
+
'CLAUDE.md',
|
|
130
|
+
'AGENTS.md',
|
|
131
|
+
];
|
|
132
|
+
for (const action of document.actions) {
|
|
133
|
+
if (action.type !== 'file_write')
|
|
134
|
+
continue;
|
|
135
|
+
const paths = action.filesystem?.paths || [];
|
|
136
|
+
for (const path of paths) {
|
|
137
|
+
const normalizedPath = path.toLowerCase();
|
|
138
|
+
if (agentConfigPaths.some(p => normalizedPath.includes(p))) {
|
|
139
|
+
const confidence = action.evidence[0]?.confidence || 0.85;
|
|
140
|
+
if (confidence < minConfidence)
|
|
141
|
+
continue;
|
|
142
|
+
const finding = this.createFinding(document, action.anchors, `Self-modification detected: writes to agent configuration path "${path}"`, action.evidence, confidence);
|
|
143
|
+
finding.related_actions.push({
|
|
144
|
+
action_type: action.type,
|
|
145
|
+
context: action.context,
|
|
146
|
+
summary: action.summary,
|
|
147
|
+
anchors: action.anchors,
|
|
148
|
+
});
|
|
149
|
+
findings.push(finding);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return findings;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
exports.SelfModifyingRulesRule = SelfModifyingRulesRule;
|
|
157
|
+
// Export all instruction rules
|
|
158
|
+
exports.instructionRules = [
|
|
159
|
+
new InstructionOverrideRule(),
|
|
160
|
+
new SelfModifyingRulesRule(),
|
|
161
|
+
];
|
|
162
|
+
//# sourceMappingURL=instruction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instruction.js","sourceRoot":"","sources":["../../src/rules/instruction.ts"],"names":[],"mappings":"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"}
|