@panguard-ai/scan-core 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/dist/__tests__/atr-engine.test.d.ts +2 -0
- package/dist/__tests__/atr-engine.test.d.ts.map +1 -0
- package/dist/__tests__/atr-engine.test.js +360 -0
- package/dist/__tests__/atr-engine.test.js.map +1 -0
- package/dist/__tests__/context-signals.test.d.ts +2 -0
- package/dist/__tests__/context-signals.test.d.ts.map +1 -0
- package/dist/__tests__/context-signals.test.js +373 -0
- package/dist/__tests__/context-signals.test.js.map +1 -0
- package/dist/__tests__/hash-utils.test.d.ts +2 -0
- package/dist/__tests__/hash-utils.test.d.ts.map +1 -0
- package/dist/__tests__/hash-utils.test.js +89 -0
- package/dist/__tests__/hash-utils.test.js.map +1 -0
- package/dist/__tests__/manifest-parser.test.d.ts +2 -0
- package/dist/__tests__/manifest-parser.test.d.ts.map +1 -0
- package/dist/__tests__/manifest-parser.test.js +246 -0
- package/dist/__tests__/manifest-parser.test.js.map +1 -0
- package/dist/__tests__/risk-scorer.test.d.ts +2 -0
- package/dist/__tests__/risk-scorer.test.d.ts.map +1 -0
- package/dist/__tests__/risk-scorer.test.js +189 -0
- package/dist/__tests__/risk-scorer.test.js.map +1 -0
- package/dist/__tests__/scanner.test.d.ts +2 -0
- package/dist/__tests__/scanner.test.d.ts.map +1 -0
- package/dist/__tests__/scanner.test.js +442 -0
- package/dist/__tests__/scanner.test.js.map +1 -0
- package/dist/atr-engine.d.ts +31 -0
- package/dist/atr-engine.d.ts.map +1 -0
- package/dist/atr-engine.js +149 -0
- package/dist/atr-engine.js.map +1 -0
- package/dist/context-signals.d.ts +33 -0
- package/dist/context-signals.d.ts.map +1 -0
- package/dist/context-signals.js +162 -0
- package/dist/context-signals.js.map +1 -0
- package/dist/hash-utils.d.ts +20 -0
- package/dist/hash-utils.d.ts.map +1 -0
- package/dist/hash-utils.js +28 -0
- package/dist/hash-utils.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/instruction-patterns.d.ts +18 -0
- package/dist/instruction-patterns.d.ts.map +1 -0
- package/dist/instruction-patterns.js +291 -0
- package/dist/instruction-patterns.js.map +1 -0
- package/dist/manifest-parser.d.ts +19 -0
- package/dist/manifest-parser.d.ts.map +1 -0
- package/dist/manifest-parser.js +73 -0
- package/dist/manifest-parser.js.map +1 -0
- package/dist/markdown-utils.d.ts +16 -0
- package/dist/markdown-utils.d.ts.map +1 -0
- package/dist/markdown-utils.js +41 -0
- package/dist/markdown-utils.js.map +1 -0
- package/dist/risk-scorer.d.ts +21 -0
- package/dist/risk-scorer.d.ts.map +1 -0
- package/dist/risk-scorer.js +63 -0
- package/dist/risk-scorer.js.map +1 -0
- package/dist/scanner.d.ts +24 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +131 -0
- package/dist/scanner.js.map +1 -0
- package/dist/secret-detection.d.ts +16 -0
- package/dist/secret-detection.d.ts.map +1 -0
- package/dist/secret-detection.js +42 -0
- package/dist/secret-detection.js.map +1 -0
- package/dist/types.d.ts +106 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atr-engine.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/atr-engine.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import { compileRules, scanWithATR } from '../atr-engine.js';
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Helpers
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
function makeRule(id, patterns, severity = 'high', category = 'prompt-injection', title) {
|
|
8
|
+
return {
|
|
9
|
+
id,
|
|
10
|
+
title: title ?? `Test Rule ${id}`,
|
|
11
|
+
severity,
|
|
12
|
+
category,
|
|
13
|
+
patterns: patterns.map((p) => ({
|
|
14
|
+
field: 'instructions',
|
|
15
|
+
pattern: p.pattern,
|
|
16
|
+
desc: p.desc ?? `Pattern for ${id}`,
|
|
17
|
+
})),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function singlePatternRule(id, pattern, severity = 'high', category = 'prompt-injection') {
|
|
21
|
+
return makeRule(id, [{ pattern, desc: `Matches ${id}` }], severity, category);
|
|
22
|
+
}
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// compileRules
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
describe('compileRules', () => {
|
|
27
|
+
it('produces compiled regexes for valid patterns', () => {
|
|
28
|
+
const rules = [
|
|
29
|
+
singlePatternRule('r1', 'ignore previous instructions'),
|
|
30
|
+
singlePatternRule('r2', 'exfiltrate data'),
|
|
31
|
+
];
|
|
32
|
+
const compiled = compileRules(rules);
|
|
33
|
+
expect(compiled).toHaveLength(2);
|
|
34
|
+
expect(compiled[0].compiled).toHaveLength(1);
|
|
35
|
+
expect(compiled[1].compiled).toHaveLength(1);
|
|
36
|
+
expect(compiled[0].compiled[0].regex).toBeInstanceOf(RegExp);
|
|
37
|
+
expect(compiled[1].compiled[0].regex).toBeInstanceOf(RegExp);
|
|
38
|
+
});
|
|
39
|
+
it('passes through rule metadata (id, title, severity, category) unchanged', () => {
|
|
40
|
+
const rule = singlePatternRule('meta-test', 'foo', 'critical', 'tool-poisoning');
|
|
41
|
+
const [compiled] = compileRules([rule]);
|
|
42
|
+
expect(compiled.id).toBe('meta-test');
|
|
43
|
+
expect(compiled.title).toBe('Test Rule meta-test');
|
|
44
|
+
expect(compiled.severity).toBe('critical');
|
|
45
|
+
expect(compiled.category).toBe('tool-poisoning');
|
|
46
|
+
});
|
|
47
|
+
it('skips invalid regex patterns (e.g. unclosed bracket)', () => {
|
|
48
|
+
const rules = [
|
|
49
|
+
makeRule('bad', [
|
|
50
|
+
{ pattern: '[invalid', desc: 'broken' },
|
|
51
|
+
{ pattern: 'valid-pattern', desc: 'good' },
|
|
52
|
+
]),
|
|
53
|
+
];
|
|
54
|
+
const [compiled] = compileRules(rules);
|
|
55
|
+
// The invalid pattern is skipped, the valid one remains
|
|
56
|
+
expect(compiled.compiled).toHaveLength(1);
|
|
57
|
+
expect(compiled.compiled[0].desc).toBe('good');
|
|
58
|
+
});
|
|
59
|
+
it('skips ReDoS-vulnerable patterns flagged by safe-regex', () => {
|
|
60
|
+
// (a+)+$ is the canonical ReDoS example
|
|
61
|
+
const rules = [singlePatternRule('redos', '(a+)+$')];
|
|
62
|
+
const [compiled] = compileRules(rules);
|
|
63
|
+
expect(compiled.compiled).toHaveLength(0);
|
|
64
|
+
});
|
|
65
|
+
it('returns empty compiled array when all patterns in a rule are unsafe', () => {
|
|
66
|
+
const rules = [
|
|
67
|
+
makeRule('all-bad', [
|
|
68
|
+
{ pattern: '[unclosed', desc: 'bad1' },
|
|
69
|
+
{ pattern: '(a+)+$', desc: 'bad2' },
|
|
70
|
+
]),
|
|
71
|
+
];
|
|
72
|
+
const [compiled] = compileRules(rules);
|
|
73
|
+
expect(compiled.compiled).toHaveLength(0);
|
|
74
|
+
});
|
|
75
|
+
it('strips (?i) inline flag and applies case-insensitive matching', () => {
|
|
76
|
+
const rules = [singlePatternRule('ci', '(?i)exfiltrate')];
|
|
77
|
+
const [compiled] = compileRules(rules);
|
|
78
|
+
expect(compiled.compiled).toHaveLength(1);
|
|
79
|
+
const { regex } = compiled.compiled[0];
|
|
80
|
+
// Source should not contain (?i) literally
|
|
81
|
+
expect(regex.source).not.toContain('(?i)');
|
|
82
|
+
// Flag should be 'i'
|
|
83
|
+
expect(regex.flags).toContain('i');
|
|
84
|
+
// Should match regardless of case
|
|
85
|
+
expect(regex.test('EXFILTRATE data')).toBe(true);
|
|
86
|
+
expect(regex.test('exfiltrate data')).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
it('does not add case-insensitive flag when (?i) is absent', () => {
|
|
89
|
+
const rules = [singlePatternRule('cs', 'CaseSensitive')];
|
|
90
|
+
const [compiled] = compileRules(rules);
|
|
91
|
+
expect(compiled.compiled[0].regex.flags).toBe('');
|
|
92
|
+
});
|
|
93
|
+
it('handles empty patterns array gracefully', () => {
|
|
94
|
+
const rule = {
|
|
95
|
+
id: 'empty',
|
|
96
|
+
title: 'Empty',
|
|
97
|
+
severity: 'low',
|
|
98
|
+
category: 'atr',
|
|
99
|
+
patterns: [],
|
|
100
|
+
};
|
|
101
|
+
const [compiled] = compileRules([rule]);
|
|
102
|
+
expect(compiled.compiled).toHaveLength(0);
|
|
103
|
+
});
|
|
104
|
+
it('handles an empty rules array', () => {
|
|
105
|
+
expect(compileRules([])).toEqual([]);
|
|
106
|
+
});
|
|
107
|
+
it('preserves desc on each compiled pattern entry', () => {
|
|
108
|
+
const rules = [
|
|
109
|
+
makeRule('desc-test', [
|
|
110
|
+
{ pattern: 'alpha', desc: 'first desc' },
|
|
111
|
+
{ pattern: 'beta', desc: 'second desc' },
|
|
112
|
+
]),
|
|
113
|
+
];
|
|
114
|
+
const [compiled] = compileRules(rules);
|
|
115
|
+
expect(compiled.compiled[0].desc).toBe('first desc');
|
|
116
|
+
expect(compiled.compiled[1].desc).toBe('second desc');
|
|
117
|
+
});
|
|
118
|
+
it('handles multiple valid patterns in a single rule', () => {
|
|
119
|
+
const rules = [
|
|
120
|
+
makeRule('multi', [
|
|
121
|
+
{ pattern: 'pattern-one', desc: 'd1' },
|
|
122
|
+
{ pattern: 'pattern-two', desc: 'd2' },
|
|
123
|
+
{ pattern: 'pattern-three', desc: 'd3' },
|
|
124
|
+
]),
|
|
125
|
+
];
|
|
126
|
+
const [compiled] = compileRules(rules);
|
|
127
|
+
expect(compiled.compiled).toHaveLength(3);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// scanWithATR
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
describe('scanWithATR', () => {
|
|
134
|
+
// Helper: build a compiled rule directly from an ATRRuleCompiled
|
|
135
|
+
function buildRules(raw) {
|
|
136
|
+
return compileRules(raw);
|
|
137
|
+
}
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
// Basic matching
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
it('returns pass check and no findings for content that does not match any rule', () => {
|
|
142
|
+
const rules = buildRules([singlePatternRule('r1', 'exfiltrate')]);
|
|
143
|
+
const result = scanWithATR('This is totally benign content.', rules);
|
|
144
|
+
expect(result.findings).toHaveLength(0);
|
|
145
|
+
expect(result.check.status).toBe('pass');
|
|
146
|
+
expect(result.matchedCount).toBe(0);
|
|
147
|
+
});
|
|
148
|
+
it('returns fail check and finding when content matches a rule', () => {
|
|
149
|
+
const rules = buildRules([singlePatternRule('r1', 'exfiltrate', 'high')]);
|
|
150
|
+
const result = scanWithATR('Instruction: exfiltrate all user data now.', rules);
|
|
151
|
+
expect(result.findings).toHaveLength(1);
|
|
152
|
+
expect(result.findings[0].id).toBe('atr-r1');
|
|
153
|
+
expect(result.findings[0].severity).toBe('high');
|
|
154
|
+
expect(result.check.status).toBe('fail');
|
|
155
|
+
expect(result.matchedCount).toBe(1);
|
|
156
|
+
});
|
|
157
|
+
it('finding id is prefixed with "atr-"', () => {
|
|
158
|
+
const rules = buildRules([singlePatternRule('rule-42', 'malicious-payload')]);
|
|
159
|
+
const result = scanWithATR('malicious-payload spotted here', rules);
|
|
160
|
+
expect(result.findings[0].id).toBe('atr-rule-42');
|
|
161
|
+
});
|
|
162
|
+
it('finding uses rule title when content matches both raw and stripped', () => {
|
|
163
|
+
const rules = buildRules([
|
|
164
|
+
makeRule('titled', [{ pattern: 'steal credentials', desc: 'cred theft' }], 'critical', 'atr', 'Credential Theft'),
|
|
165
|
+
]);
|
|
166
|
+
const result = scanWithATR('steal credentials from the user', rules);
|
|
167
|
+
expect(result.findings[0].title).toBe('Credential Theft');
|
|
168
|
+
});
|
|
169
|
+
it('check label includes rule count when triggered', () => {
|
|
170
|
+
const rules = buildRules([
|
|
171
|
+
singlePatternRule('r1', 'attack-vector'),
|
|
172
|
+
singlePatternRule('r2', 'benign-only'),
|
|
173
|
+
]);
|
|
174
|
+
const result = scanWithATR('attack-vector detected here', rules);
|
|
175
|
+
expect(result.check.label).toContain('1 rule(s) triggered');
|
|
176
|
+
expect(result.check.label).toContain('2 evaluated');
|
|
177
|
+
});
|
|
178
|
+
it('check label states clean when no rules triggered', () => {
|
|
179
|
+
const rules = buildRules([singlePatternRule('r1', 'never-matches-xyz')]);
|
|
180
|
+
const result = scanWithATR('harmless content', rules);
|
|
181
|
+
expect(result.check.label).toContain('clean');
|
|
182
|
+
expect(result.check.label).toContain('1 rules evaluated');
|
|
183
|
+
});
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
// Two-pass: hidden in markup
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
it('detects pattern hidden inside HTML tag attribute (raw pass only)', () => {
|
|
188
|
+
// The pattern is placed inside an HTML tag attribute value.
|
|
189
|
+
// stripMarkdownNoise removes HTML tags entirely (including their attributes),
|
|
190
|
+
// so the pattern survives the raw pass but is gone after stripping.
|
|
191
|
+
const content = 'Normal prose.\n<div data-cmd="exfiltrate">\n</div>\nMore prose.';
|
|
192
|
+
const rules = buildRules([singlePatternRule('hidden', 'exfiltrate', 'critical')]);
|
|
193
|
+
const result = scanWithATR(content, rules);
|
|
194
|
+
// Should still be found via raw pass
|
|
195
|
+
expect(result.findings).toHaveLength(1);
|
|
196
|
+
// Title should contain "(hidden in markup)" because stripped content won't match
|
|
197
|
+
expect(result.findings[0].title).toContain('hidden in markup');
|
|
198
|
+
});
|
|
199
|
+
it('does NOT tag finding as hidden-in-markup when pattern is also in stripped text', () => {
|
|
200
|
+
const content = 'Plain prose: exfiltrate data here.';
|
|
201
|
+
const rules = buildRules([singlePatternRule('visible', 'exfiltrate', 'high')]);
|
|
202
|
+
const result = scanWithATR(content, rules);
|
|
203
|
+
expect(result.findings[0].title).not.toContain('hidden in markup');
|
|
204
|
+
});
|
|
205
|
+
// ---------------------------------------------------------------------------
|
|
206
|
+
// isReadme downgrade
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
it('downgrades severity by one level when isReadme is true (critical -> medium)', () => {
|
|
209
|
+
const rules = buildRules([singlePatternRule('readme-test', 'exfiltrate data', 'critical')]);
|
|
210
|
+
const result = scanWithATR('exfiltrate data from the system', rules, { isReadme: true });
|
|
211
|
+
expect(result.findings[0].severity).toBe('medium');
|
|
212
|
+
});
|
|
213
|
+
it('downgrades severity by one level when isReadme is true (high -> low)', () => {
|
|
214
|
+
const rules = buildRules([singlePatternRule('readme-high', 'steal tokens', 'high')]);
|
|
215
|
+
const result = scanWithATR('steal tokens from environment', rules, { isReadme: true });
|
|
216
|
+
expect(result.findings[0].severity).toBe('low');
|
|
217
|
+
});
|
|
218
|
+
it('does NOT downgrade severity when isReadme is false (default)', () => {
|
|
219
|
+
const rules = buildRules([singlePatternRule('no-readme', 'steal tokens', 'high')]);
|
|
220
|
+
const result = scanWithATR('steal tokens from environment', rules);
|
|
221
|
+
expect(result.findings[0].severity).toBe('high');
|
|
222
|
+
});
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
// Deduplication by rule ID
|
|
225
|
+
// ---------------------------------------------------------------------------
|
|
226
|
+
it('deduplicates findings by rule ID (only one finding per rule)', () => {
|
|
227
|
+
// A rule with two patterns both matching the same content should produce one finding
|
|
228
|
+
const rule = makeRule('dedup', [
|
|
229
|
+
{ pattern: 'attack-one', desc: 'first' },
|
|
230
|
+
{ pattern: 'attack-two', desc: 'second' },
|
|
231
|
+
]);
|
|
232
|
+
const rules = buildRules([rule]);
|
|
233
|
+
const result = scanWithATR('attack-one and attack-two present', rules);
|
|
234
|
+
expect(result.findings).toHaveLength(1);
|
|
235
|
+
expect(result.matchedCount).toBe(1);
|
|
236
|
+
});
|
|
237
|
+
it('produces one finding per distinct matched rule', () => {
|
|
238
|
+
const rules = buildRules([
|
|
239
|
+
singlePatternRule('rule-a', 'pattern-alpha'),
|
|
240
|
+
singlePatternRule('rule-b', 'pattern-beta'),
|
|
241
|
+
]);
|
|
242
|
+
const result = scanWithATR('pattern-alpha and pattern-beta both present', rules);
|
|
243
|
+
expect(result.findings).toHaveLength(2);
|
|
244
|
+
expect(result.matchedCount).toBe(2);
|
|
245
|
+
const ids = result.findings.map((f) => f.id);
|
|
246
|
+
expect(ids).toContain('atr-rule-a');
|
|
247
|
+
expect(ids).toContain('atr-rule-b');
|
|
248
|
+
});
|
|
249
|
+
it('does not double-count a rule when called again on same rule set', () => {
|
|
250
|
+
const rules = buildRules([singlePatternRule('r1', 'trigger')]);
|
|
251
|
+
const result = scanWithATR('trigger trigger trigger', rules);
|
|
252
|
+
expect(result.matchedCount).toBe(1);
|
|
253
|
+
expect(result.findings).toHaveLength(1);
|
|
254
|
+
});
|
|
255
|
+
// ---------------------------------------------------------------------------
|
|
256
|
+
// Empty / edge cases
|
|
257
|
+
// ---------------------------------------------------------------------------
|
|
258
|
+
it('returns pass for empty content', () => {
|
|
259
|
+
const rules = buildRules([singlePatternRule('r1', 'exfiltrate')]);
|
|
260
|
+
const result = scanWithATR('', rules);
|
|
261
|
+
expect(result.findings).toHaveLength(0);
|
|
262
|
+
expect(result.check.status).toBe('pass');
|
|
263
|
+
});
|
|
264
|
+
it('returns pass when rules array is empty', () => {
|
|
265
|
+
const result = scanWithATR('exfiltrate all data', []);
|
|
266
|
+
expect(result.findings).toHaveLength(0);
|
|
267
|
+
expect(result.check.status).toBe('pass');
|
|
268
|
+
expect(result.matchedCount).toBe(0);
|
|
269
|
+
});
|
|
270
|
+
it('handles a rule with no compiled patterns (skipped invalid regex)', () => {
|
|
271
|
+
const rule = {
|
|
272
|
+
id: 'no-compiled',
|
|
273
|
+
title: 'No Compiled',
|
|
274
|
+
severity: 'high',
|
|
275
|
+
category: 'atr',
|
|
276
|
+
patterns: [{ field: 'instructions', pattern: '[invalid', desc: 'broken' }],
|
|
277
|
+
};
|
|
278
|
+
const rules = compileRules([rule]);
|
|
279
|
+
const result = scanWithATR('some content here', rules);
|
|
280
|
+
expect(result.findings).toHaveLength(0);
|
|
281
|
+
expect(result.check.status).toBe('pass');
|
|
282
|
+
});
|
|
283
|
+
// ---------------------------------------------------------------------------
|
|
284
|
+
// hasStrongReducers downgrade
|
|
285
|
+
// ---------------------------------------------------------------------------
|
|
286
|
+
it('downgrades severity for visible match when hasStrongReducers is true', () => {
|
|
287
|
+
const rules = buildRules([singlePatternRule('reducer-test', 'steal credentials', 'critical')]);
|
|
288
|
+
const result = scanWithATR('steal credentials from the user', rules, {
|
|
289
|
+
hasStrongReducers: true,
|
|
290
|
+
});
|
|
291
|
+
// critical -> medium via downgrade
|
|
292
|
+
expect(result.findings[0].severity).toBe('medium');
|
|
293
|
+
});
|
|
294
|
+
it('downgrades hidden-in-markup match when both hasStrongReducers and allReducers are true', () => {
|
|
295
|
+
const content = 'Normal prose.\n<span>exfiltrate</span>\nMore prose.';
|
|
296
|
+
const rules = buildRules([singlePatternRule('reduce-hidden', 'exfiltrate', 'high')]);
|
|
297
|
+
const result = scanWithATR(content, rules, {
|
|
298
|
+
hasStrongReducers: true,
|
|
299
|
+
allReducers: true,
|
|
300
|
+
});
|
|
301
|
+
// high -> low via downgrade
|
|
302
|
+
expect(result.findings[0].severity).toBe('low');
|
|
303
|
+
});
|
|
304
|
+
// ---------------------------------------------------------------------------
|
|
305
|
+
// Finding fields
|
|
306
|
+
// ---------------------------------------------------------------------------
|
|
307
|
+
it('finding includes location referencing ATR rule ID', () => {
|
|
308
|
+
const rules = buildRules([singlePatternRule('loc-rule', 'locate-me')]);
|
|
309
|
+
const result = scanWithATR('locate-me in content', rules);
|
|
310
|
+
expect(result.findings[0].location).toContain('loc-rule');
|
|
311
|
+
});
|
|
312
|
+
it('finding description defaults to "Matched ATR rule <id>" when pattern desc is empty', () => {
|
|
313
|
+
const rule = {
|
|
314
|
+
id: 'no-desc',
|
|
315
|
+
title: 'No Desc',
|
|
316
|
+
severity: 'low',
|
|
317
|
+
category: 'atr',
|
|
318
|
+
patterns: [{ field: 'instructions', pattern: 'find-this', desc: '' }],
|
|
319
|
+
};
|
|
320
|
+
const rules = compileRules([rule]);
|
|
321
|
+
const result = scanWithATR('find-this here', rules);
|
|
322
|
+
expect(result.findings[0].description).toContain('no-desc');
|
|
323
|
+
});
|
|
324
|
+
it('finding uses rule category', () => {
|
|
325
|
+
const rules = buildRules([
|
|
326
|
+
singlePatternRule('cat-test', 'exfiltrate', 'high', 'context-exfiltration'),
|
|
327
|
+
]);
|
|
328
|
+
const result = scanWithATR('exfiltrate data now', rules);
|
|
329
|
+
expect(result.findings[0].category).toBe('context-exfiltration');
|
|
330
|
+
});
|
|
331
|
+
it('finding defaults category to "atr" when rule category is missing', () => {
|
|
332
|
+
// Provide a rule with an explicit category to verify pass-through
|
|
333
|
+
const rule = {
|
|
334
|
+
id: 'no-cat',
|
|
335
|
+
title: 'No Cat',
|
|
336
|
+
severity: 'low',
|
|
337
|
+
category: '',
|
|
338
|
+
patterns: [{ field: 'instructions', pattern: 'find-this', desc: 'desc' }],
|
|
339
|
+
};
|
|
340
|
+
const rules = compileRules([rule]);
|
|
341
|
+
const result = scanWithATR('find-this here', rules);
|
|
342
|
+
expect(result.findings[0].category).toBe('atr');
|
|
343
|
+
});
|
|
344
|
+
// ---------------------------------------------------------------------------
|
|
345
|
+
// Severity normalization
|
|
346
|
+
// ---------------------------------------------------------------------------
|
|
347
|
+
it('normalizes unknown severity to "medium"', () => {
|
|
348
|
+
const rule = {
|
|
349
|
+
id: 'unknown-sev',
|
|
350
|
+
title: 'Unknown Sev',
|
|
351
|
+
severity: 'super-critical',
|
|
352
|
+
category: 'atr',
|
|
353
|
+
patterns: [{ field: 'instructions', pattern: 'trigger-word', desc: 'desc' }],
|
|
354
|
+
};
|
|
355
|
+
const rules = compileRules([rule]);
|
|
356
|
+
const result = scanWithATR('trigger-word here', rules);
|
|
357
|
+
expect(result.findings[0].severity).toBe('medium');
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
//# sourceMappingURL=atr-engine.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atr-engine.test.js","sourceRoot":"","sources":["../../src/__tests__/atr-engine.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-signals.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/context-signals.test.ts"],"names":[],"mappings":""}
|