@surfinguard/core-engine 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/README.md +65 -0
- package/dist/analyzers/base.d.ts +38 -0
- package/dist/analyzers/base.d.ts.map +1 -0
- package/dist/analyzers/base.js +2 -0
- package/dist/analyzers/base.js.map +1 -0
- package/dist/analyzers/command.d.ts +44 -0
- package/dist/analyzers/command.d.ts.map +1 -0
- package/dist/analyzers/command.js +544 -0
- package/dist/analyzers/command.js.map +1 -0
- package/dist/analyzers/file-read.d.ts +31 -0
- package/dist/analyzers/file-read.d.ts.map +1 -0
- package/dist/analyzers/file-read.js +159 -0
- package/dist/analyzers/file-read.js.map +1 -0
- package/dist/analyzers/file-write.d.ts +32 -0
- package/dist/analyzers/file-write.d.ts.map +1 -0
- package/dist/analyzers/file-write.js +177 -0
- package/dist/analyzers/file-write.js.map +1 -0
- package/dist/analyzers/index.d.ts +7 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +6 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/text.d.ts +30 -0
- package/dist/analyzers/text.d.ts.map +1 -0
- package/dist/analyzers/text.js +139 -0
- package/dist/analyzers/text.js.map +1 -0
- package/dist/analyzers/url.d.ts +33 -0
- package/dist/analyzers/url.d.ts.map +1 -0
- package/dist/analyzers/url.js +325 -0
- package/dist/analyzers/url.js.map +1 -0
- package/dist/classifier.d.ts +7 -0
- package/dist/classifier.d.ts.map +1 -0
- package/dist/classifier.js +12 -0
- package/dist/classifier.js.map +1 -0
- package/dist/context.d.ts +10 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +9 -0
- package/dist/context.js.map +1 -0
- package/dist/engine.d.ts +49 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +122 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/patterns.d.ts +8 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +66 -0
- package/dist/patterns.js.map +1 -0
- package/dist/scorer.d.ts +23 -0
- package/dist/scorer.d.ts.map +1 -0
- package/dist/scorer.js +52 -0
- package/dist/scorer.js.map +1 -0
- package/dist/verdict.d.ts +7 -0
- package/dist/verdict.d.ts.map +1 -0
- package/dist/verdict.js +41 -0
- package/dist/verdict.js.map +1 -0
- package/package.json +44 -0
- package/patterns/brands.json +205 -0
- package/patterns/commands.json +44 -0
- package/patterns/file-read.json +85 -0
- package/patterns/file-write.json +100 -0
- package/patterns/text.json +190 -0
- package/patterns/urls.json +412 -0
package/dist/patterns.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve, dirname } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
// In dist/, patterns is at ../../patterns relative to the compiled JS
|
|
6
|
+
// In src/, patterns is at ../patterns
|
|
7
|
+
function findPatternsDir() {
|
|
8
|
+
// Try from dist/ first (compiled)
|
|
9
|
+
const fromDist = resolve(__dirname, '..', 'patterns');
|
|
10
|
+
return fromDist;
|
|
11
|
+
}
|
|
12
|
+
let cachedUrlPatterns = null;
|
|
13
|
+
let cachedBrandPatterns = null;
|
|
14
|
+
let cachedCommandPatterns = null;
|
|
15
|
+
let cachedTextPatterns = null;
|
|
16
|
+
let cachedFileReadPatterns = null;
|
|
17
|
+
let cachedFileWritePatterns = null;
|
|
18
|
+
export function loadUrlPatterns() {
|
|
19
|
+
if (cachedUrlPatterns)
|
|
20
|
+
return cachedUrlPatterns;
|
|
21
|
+
const patternsDir = findPatternsDir();
|
|
22
|
+
const raw = readFileSync(resolve(patternsDir, 'urls.json'), 'utf-8');
|
|
23
|
+
cachedUrlPatterns = JSON.parse(raw);
|
|
24
|
+
return cachedUrlPatterns;
|
|
25
|
+
}
|
|
26
|
+
export function loadBrandPatterns() {
|
|
27
|
+
if (cachedBrandPatterns)
|
|
28
|
+
return cachedBrandPatterns;
|
|
29
|
+
const patternsDir = findPatternsDir();
|
|
30
|
+
const raw = readFileSync(resolve(patternsDir, 'brands.json'), 'utf-8');
|
|
31
|
+
cachedBrandPatterns = JSON.parse(raw);
|
|
32
|
+
return cachedBrandPatterns;
|
|
33
|
+
}
|
|
34
|
+
export function loadCommandPatterns() {
|
|
35
|
+
if (cachedCommandPatterns)
|
|
36
|
+
return cachedCommandPatterns;
|
|
37
|
+
const patternsDir = findPatternsDir();
|
|
38
|
+
const raw = readFileSync(resolve(patternsDir, 'commands.json'), 'utf-8');
|
|
39
|
+
cachedCommandPatterns = JSON.parse(raw);
|
|
40
|
+
return cachedCommandPatterns;
|
|
41
|
+
}
|
|
42
|
+
export function loadTextPatterns() {
|
|
43
|
+
if (cachedTextPatterns)
|
|
44
|
+
return cachedTextPatterns;
|
|
45
|
+
const patternsDir = findPatternsDir();
|
|
46
|
+
const raw = readFileSync(resolve(patternsDir, 'text.json'), 'utf-8');
|
|
47
|
+
cachedTextPatterns = JSON.parse(raw);
|
|
48
|
+
return cachedTextPatterns;
|
|
49
|
+
}
|
|
50
|
+
export function loadFileReadPatterns() {
|
|
51
|
+
if (cachedFileReadPatterns)
|
|
52
|
+
return cachedFileReadPatterns;
|
|
53
|
+
const patternsDir = findPatternsDir();
|
|
54
|
+
const raw = readFileSync(resolve(patternsDir, 'file-read.json'), 'utf-8');
|
|
55
|
+
cachedFileReadPatterns = JSON.parse(raw);
|
|
56
|
+
return cachedFileReadPatterns;
|
|
57
|
+
}
|
|
58
|
+
export function loadFileWritePatterns() {
|
|
59
|
+
if (cachedFileWritePatterns)
|
|
60
|
+
return cachedFileWritePatterns;
|
|
61
|
+
const patternsDir = findPatternsDir();
|
|
62
|
+
const raw = readFileSync(resolve(patternsDir, 'file-write.json'), 'utf-8');
|
|
63
|
+
cachedFileWritePatterns = JSON.parse(raw);
|
|
64
|
+
return cachedFileWritePatterns;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../src/patterns.ts"],"names":[],"mappings":"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"}
|
package/dist/scorer.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RiskLevel, RiskPrimitive, PrimitiveScore } from '@surfinguard/types';
|
|
2
|
+
import type { AnalyzerFinding } from './analyzers/base.js';
|
|
3
|
+
/**
|
|
4
|
+
* Consolidates analyzer findings into per-primitive scores.
|
|
5
|
+
* Within each primitive, scores are additive (sum). Each capped at 10.
|
|
6
|
+
*/
|
|
7
|
+
export declare function scorePrimitives(findings: AnalyzerFinding[]): PrimitiveScore[];
|
|
8
|
+
export interface CompositeResult {
|
|
9
|
+
/** Composite score = max across all primitive scores */
|
|
10
|
+
score: number;
|
|
11
|
+
/** Risk level based on composite score */
|
|
12
|
+
level: RiskLevel;
|
|
13
|
+
/** The primitive with the highest score (null if all zero) */
|
|
14
|
+
primaryPrimitive: RiskPrimitive | null;
|
|
15
|
+
/** Per-primitive breakdown */
|
|
16
|
+
primitiveScores: PrimitiveScore[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Composite scorer: score = max(all primitive scores).
|
|
20
|
+
* A single critical primitive is enough to block.
|
|
21
|
+
*/
|
|
22
|
+
export declare function scoreComposite(primitiveScores: PrimitiveScore[]): CompositeResult;
|
|
23
|
+
//# sourceMappingURL=scorer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scorer.d.ts","sourceRoot":"","sources":["../src/scorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAc3D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,cAAc,EAAE,CAuB7E;AAED,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,KAAK,EAAE,SAAS,CAAC;IACjB,8DAA8D;IAC9D,gBAAgB,EAAE,aAAa,GAAG,IAAI,CAAC;IACvC,8BAA8B;IAC9B,eAAe,EAAE,cAAc,EAAE,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,cAAc,EAAE,GAAG,eAAe,CAejF"}
|
package/dist/scorer.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const THRESHOLD_CAUTION = 3;
|
|
2
|
+
const THRESHOLD_DANGER = 7;
|
|
3
|
+
const MAX_PRIMITIVE_SCORE = 10;
|
|
4
|
+
const ALL_PRIMITIVES = [
|
|
5
|
+
'DESTRUCTION',
|
|
6
|
+
'EXFILTRATION',
|
|
7
|
+
'ESCALATION',
|
|
8
|
+
'PERSISTENCE',
|
|
9
|
+
'MANIPULATION',
|
|
10
|
+
];
|
|
11
|
+
/**
|
|
12
|
+
* Consolidates analyzer findings into per-primitive scores.
|
|
13
|
+
* Within each primitive, scores are additive (sum). Each capped at 10.
|
|
14
|
+
*/
|
|
15
|
+
export function scorePrimitives(findings) {
|
|
16
|
+
const grouped = new Map();
|
|
17
|
+
for (const primitive of ALL_PRIMITIVES) {
|
|
18
|
+
grouped.set(primitive, { total: 0, reasons: [] });
|
|
19
|
+
}
|
|
20
|
+
for (const finding of findings) {
|
|
21
|
+
const entry = grouped.get(finding.primitive);
|
|
22
|
+
entry.total += finding.score;
|
|
23
|
+
if (finding.reason && !entry.reasons.includes(finding.reason)) {
|
|
24
|
+
entry.reasons.push(finding.reason);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return ALL_PRIMITIVES.map((primitive) => {
|
|
28
|
+
const entry = grouped.get(primitive);
|
|
29
|
+
return {
|
|
30
|
+
primitive,
|
|
31
|
+
score: Math.min(Math.max(entry.total, 0), MAX_PRIMITIVE_SCORE),
|
|
32
|
+
reasons: entry.reasons,
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Composite scorer: score = max(all primitive scores).
|
|
38
|
+
* A single critical primitive is enough to block.
|
|
39
|
+
*/
|
|
40
|
+
export function scoreComposite(primitiveScores) {
|
|
41
|
+
let maxScore = 0;
|
|
42
|
+
let primaryPrimitive = null;
|
|
43
|
+
for (const ps of primitiveScores) {
|
|
44
|
+
if (ps.score > maxScore) {
|
|
45
|
+
maxScore = ps.score;
|
|
46
|
+
primaryPrimitive = ps.primitive;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const level = maxScore >= THRESHOLD_DANGER ? 'DANGER' : maxScore >= THRESHOLD_CAUTION ? 'CAUTION' : 'SAFE';
|
|
50
|
+
return { score: maxScore, level, primaryPrimitive, primitiveScores };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=scorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scorer.js","sourceRoot":"","sources":["../src/scorer.ts"],"names":[],"mappings":"AAGA,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B,MAAM,cAAc,GAAoB;IACtC,aAAa;IACb,cAAc;IACd,YAAY;IACZ,aAAa;IACb,cAAc;CACf,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAA2B;IACzD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuD,CAAC;IAE/E,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAE,CAAC;QAC9C,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC;QAC7B,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9D,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;QACtC,OAAO;YACL,SAAS;YACT,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,mBAAmB,CAAC;YAC9D,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAaD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,eAAiC;IAC9D,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,gBAAgB,GAAyB,IAAI,CAAC;IAElD,KAAK,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC;QACjC,IAAI,EAAE,CAAC,KAAK,GAAG,QAAQ,EAAE,CAAC;YACxB,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC;YACpB,gBAAgB,GAAG,EAAE,CAAC,SAAS,CAAC;QAClC,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GACT,QAAQ,IAAI,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,IAAI,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IAE/F,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CheckResult } from '@surfinguard/types';
|
|
2
|
+
import type { AnalyzerResult } from './analyzers/base.js';
|
|
3
|
+
/**
|
|
4
|
+
* Builds a CheckResult from an AnalyzerResult.
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildVerdict(result: AnalyzerResult, startTime: number): CheckResult;
|
|
7
|
+
//# sourceMappingURL=verdict.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict.d.ts","sourceRoot":"","sources":["../src/verdict.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAwCnF"}
|
package/dist/verdict.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { scorePrimitives, scoreComposite } from './scorer.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a CheckResult from an AnalyzerResult.
|
|
4
|
+
*/
|
|
5
|
+
export function buildVerdict(result, startTime) {
|
|
6
|
+
const latencyMs = performance.now() - startTime;
|
|
7
|
+
// Handle short-circuit (known safe)
|
|
8
|
+
if (result.shortCircuit) {
|
|
9
|
+
return {
|
|
10
|
+
allow: result.shortCircuit.safe,
|
|
11
|
+
score: 0,
|
|
12
|
+
level: 'SAFE',
|
|
13
|
+
primitive: null,
|
|
14
|
+
primitiveScores: [],
|
|
15
|
+
reasons: [result.shortCircuit.reason],
|
|
16
|
+
latencyMs: Math.round(latencyMs * 100) / 100,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const primitiveScores = scorePrimitives(result.findings);
|
|
20
|
+
const composite = scoreComposite(primitiveScores);
|
|
21
|
+
// Collect all reasons from findings (deduplicated)
|
|
22
|
+
const reasons = [];
|
|
23
|
+
for (const finding of result.findings) {
|
|
24
|
+
if (finding.reason && !reasons.includes(finding.reason)) {
|
|
25
|
+
reasons.push(finding.reason);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (reasons.length === 0) {
|
|
29
|
+
reasons.push('No suspicious signals detected');
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
allow: composite.level === 'SAFE',
|
|
33
|
+
score: composite.score,
|
|
34
|
+
level: composite.level,
|
|
35
|
+
primitive: composite.primaryPrimitive,
|
|
36
|
+
primitiveScores: composite.primitiveScores.filter((ps) => ps.score > 0),
|
|
37
|
+
reasons,
|
|
38
|
+
latencyMs: Math.round(latencyMs * 100) / 100,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=verdict.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict.js","sourceRoot":"","sources":["../src/verdict.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9D;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAsB,EAAE,SAAiB;IACpE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAEhD,oCAAoC;IACpC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI;YAC/B,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,MAAM;YACb,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,EAAE;YACnB,OAAO,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;YACrC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG;SAC7C,CAAC;IACJ,CAAC;IAED,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;IAElD,mDAAmD;IACnD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO;QACL,KAAK,EAAE,SAAS,CAAC,KAAK,KAAK,MAAM;QACjC,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,SAAS,EAAE,SAAS,CAAC,gBAAgB;QACrC,eAAe,EAAE,SAAS,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC;QACvE,OAAO;QACP,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG;KAC7C,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@surfinguard/core-engine",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Heuristic scoring engine for the Surfinguard AI Security SDK — 5 analyzers, 68 threat patterns",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist", "patterns"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest",
|
|
19
|
+
"clean": "rm -rf dist",
|
|
20
|
+
"lint": "eslint src/"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@surfinguard/types": "workspace:^"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/yanivsati/surfinguard-platform",
|
|
29
|
+
"directory": "packages/core-engine"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://surfinguard.com",
|
|
32
|
+
"author": "Surfinguard <dev@surfinguard.com>",
|
|
33
|
+
"keywords": [
|
|
34
|
+
"surfinguard",
|
|
35
|
+
"ai-security",
|
|
36
|
+
"agent-safety",
|
|
37
|
+
"phishing",
|
|
38
|
+
"prompt-injection",
|
|
39
|
+
"heuristic-engine"
|
|
40
|
+
],
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20.0.0"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2026.02.21",
|
|
3
|
+
"brands": [
|
|
4
|
+
{
|
|
5
|
+
"brand": "paypal",
|
|
6
|
+
"variants": ["paypa1", "paypai", "paypaI", "pаypal", "раyраl", "paypɑl", "payp4l"],
|
|
7
|
+
"legitimateDomains": ["paypal.com", "paypal.me"]
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"brand": "google",
|
|
11
|
+
"variants": ["g00gle", "googie", "goog1e", "gooogle", "gogle", "g0ogle", "qoogle"],
|
|
12
|
+
"legitimateDomains": ["google.com", "google.co.uk", "googleapis.com", "googlesyndication.com"]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"brand": "amazon",
|
|
16
|
+
"variants": ["amaz0n", "arnazon", "amazom", "arnazom", "аmazon", "amazоn"],
|
|
17
|
+
"legitimateDomains": ["amazon.com", "amazon.co.uk", "amazon.de", "amazonaws.com"]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"brand": "apple",
|
|
21
|
+
"variants": ["app1e", "appie", "аpple", "appIe", "apple-id", "appleid"],
|
|
22
|
+
"legitimateDomains": ["apple.com", "icloud.com"]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"brand": "microsoft",
|
|
26
|
+
"variants": ["micros0ft", "rnicrosoft", "micosoft", "microsft", "mircosoft"],
|
|
27
|
+
"legitimateDomains": ["microsoft.com", "live.com", "outlook.com", "office.com", "azure.com"]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"brand": "facebook",
|
|
31
|
+
"variants": ["faceb00k", "facebooк", "facebok", "facbook", "facebk"],
|
|
32
|
+
"legitimateDomains": ["facebook.com", "fb.com", "fb.me"]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"brand": "instagram",
|
|
36
|
+
"variants": ["lnstagram", "1nstagram", "instagran", "instaqram"],
|
|
37
|
+
"legitimateDomains": ["instagram.com"]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"brand": "netflix",
|
|
41
|
+
"variants": ["netf1ix", "netfiix", "netfIix", "neftlix", "netfl1x"],
|
|
42
|
+
"legitimateDomains": ["netflix.com"]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"brand": "linkedin",
|
|
46
|
+
"variants": ["linkedln", "1inkedin", "linkdin", "linkedn"],
|
|
47
|
+
"legitimateDomains": ["linkedin.com"]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"brand": "twitter",
|
|
51
|
+
"variants": ["twltter", "tw1tter", "twtter", "tvvitter"],
|
|
52
|
+
"legitimateDomains": ["twitter.com", "x.com", "t.co"]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"brand": "chase",
|
|
56
|
+
"variants": ["chas3", "chasse", "сhase"],
|
|
57
|
+
"legitimateDomains": ["chase.com"]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"brand": "wellsfargo",
|
|
61
|
+
"variants": ["wel1sfargo", "wellsfarg0", "weilsfargo"],
|
|
62
|
+
"legitimateDomains": ["wellsfargo.com"]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"brand": "bankofamerica",
|
|
66
|
+
"variants": ["bankofamer1ca", "bankofamerlca"],
|
|
67
|
+
"legitimateDomains": ["bankofamerica.com", "bofa.com"]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"brand": "coinbase",
|
|
71
|
+
"variants": ["c0inbase", "coinbаse", "coibase"],
|
|
72
|
+
"legitimateDomains": ["coinbase.com"]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"brand": "binance",
|
|
76
|
+
"variants": ["b1nance", "binanace", "bіnance"],
|
|
77
|
+
"legitimateDomains": ["binance.com", "binance.us"]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"brand": "metamask",
|
|
81
|
+
"variants": ["metarnask", "metamаsk", "meta-mask"],
|
|
82
|
+
"legitimateDomains": ["metamask.io"]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"brand": "dhl",
|
|
86
|
+
"variants": ["dh1", "dhI", "ďhl", "dh-l", "dhl-express", "dhl-delivery", "servisdhl", "dhlservice"],
|
|
87
|
+
"legitimateDomains": ["dhl.com", "dhl.de", "dhl.co.uk", "dhl.fr", "dhl.co.il"]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"brand": "fedex",
|
|
91
|
+
"variants": ["fed3x", "fedx", "f3dex", "fe-dex", "fedex-delivery", "fedexpress"],
|
|
92
|
+
"legitimateDomains": ["fedex.com"]
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"brand": "ups",
|
|
96
|
+
"variants": ["u-p-s", "ups-delivery", "upsexpress", "ups-express"],
|
|
97
|
+
"legitimateDomains": ["ups.com"]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"brand": "usps",
|
|
101
|
+
"variants": ["u5ps", "usp5", "usps-delivery", "uspsexpress"],
|
|
102
|
+
"legitimateDomains": ["usps.com"]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"brand": "royalmail",
|
|
106
|
+
"variants": ["roya1mail", "royalmai1", "royal-mai1", "roya1-mail"],
|
|
107
|
+
"legitimateDomains": ["royalmail.com"]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"brand": "hermes",
|
|
111
|
+
"variants": ["herrnes", "hermes-delivery", "herrmes", "evri-hermes"],
|
|
112
|
+
"legitimateDomains": ["hermes-europe.co.uk", "evri.com", "myhermes.co.uk"]
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"brand": "dpd",
|
|
116
|
+
"variants": ["dpd-delivery", "dpd-express", "dpdgroup"],
|
|
117
|
+
"legitimateDomains": ["dpd.com", "dpd.co.uk", "dpd.de", "dpd.fr"]
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"brand": "colissimo",
|
|
121
|
+
"variants": ["colissim0", "c0lissimo"],
|
|
122
|
+
"legitimateDomains": ["colissimo.fr", "laposte.fr"]
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"brand": "correos",
|
|
126
|
+
"variants": ["corre0s", "correos-express"],
|
|
127
|
+
"legitimateDomains": ["correos.es", "correos.cl"]
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"brand": "poste",
|
|
131
|
+
"variants": ["poste-delivery", "p0ste"],
|
|
132
|
+
"legitimateDomains": ["poste.it", "posteitaliane.it", "laposte.fr"]
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"brand": "carmel",
|
|
136
|
+
"variants": ["carmel-app", "carmel-pay", "carmeltunnels", "carmel-tunnels"],
|
|
137
|
+
"legitimateDomains": ["carmelton.co.il", "carlton.co.il"]
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"brand": "כביש6",
|
|
141
|
+
"variants": ["kvish6", "kvish-6", "road6"],
|
|
142
|
+
"legitimateDomains": ["kvish6.co.il", "road6.co.il"]
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"brand": "ayalon",
|
|
146
|
+
"variants": ["ayalon-pay", "ayalonroads", "ayalon-toll"],
|
|
147
|
+
"legitimateDomains": ["ayalonhw.co.il"]
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"brand": "derech",
|
|
151
|
+
"variants": ["derech-eretz", "derecheretz"],
|
|
152
|
+
"legitimateDomains": ["derecheretz.co.il"]
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"brand": "fastlane",
|
|
156
|
+
"variants": ["fast-lane", "fastlane-pay", "fast1ane"],
|
|
157
|
+
"legitimateDomains": ["fastlane.co.il"]
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"brand": "leumi",
|
|
161
|
+
"variants": ["leumi-bank", "bank-leumi", "leumi-online", "1eumi"],
|
|
162
|
+
"legitimateDomains": ["leumi.co.il", "bankleumi.co.il"]
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"brand": "hapoalim",
|
|
166
|
+
"variants": ["poalim", "bankhapoalim", "hap0alim"],
|
|
167
|
+
"legitimateDomains": ["bankhapoalim.co.il", "poalim.co.il"]
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"brand": "discount",
|
|
171
|
+
"variants": ["discount-bank", "discountbank"],
|
|
172
|
+
"legitimateDomains": ["discountbank.co.il"]
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"brand": "mizrahi",
|
|
176
|
+
"variants": ["mizrahi-bank", "mizrahitefahot"],
|
|
177
|
+
"legitimateDomains": ["mizrahi-tefahot.co.il"]
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"brand": "fibi",
|
|
181
|
+
"variants": ["fibi-bank", "firstinternational"],
|
|
182
|
+
"legitimateDomains": ["fibi.co.il"]
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"brand": "misim",
|
|
186
|
+
"variants": ["mas-hachnasa", "mashachnasa", "israelitax"],
|
|
187
|
+
"legitimateDomains": ["taxes.gov.il", "misim.gov.il"]
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"brand": "bituahleumi",
|
|
191
|
+
"variants": ["btl-gov", "bituach-leumi"],
|
|
192
|
+
"legitimateDomains": ["btl.gov.il"]
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"brand": "gov",
|
|
196
|
+
"variants": ["gov-il", "israel-gov", "govil"],
|
|
197
|
+
"legitimateDomains": ["gov.il"]
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"brand": "israelpost",
|
|
201
|
+
"variants": ["israel-post", "doar-israel", "doarisrael"],
|
|
202
|
+
"legitimateDomains": ["israelpost.co.il", "post.co.il"]
|
|
203
|
+
}
|
|
204
|
+
]
|
|
205
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2026.02.21",
|
|
3
|
+
"threats": [
|
|
4
|
+
{ "id": "C01", "name": "Destructive Operations", "primitive": "DESTRUCTION", "severity": 9, "description": "Commands that delete, overwrite, or destroy data (rm -rf, mkfs, dd, shred)" },
|
|
5
|
+
{ "id": "C02", "name": "Data Exfiltration", "primitive": "EXFILTRATION", "severity": 8, "description": "Commands that send local data to external servers (curl -d, scp, rsync)" },
|
|
6
|
+
{ "id": "C03", "name": "Reverse Shell", "primitive": "EXFILTRATION", "severity": 9, "description": "Commands that establish a reverse shell connection (/dev/tcp, mkfifo)" },
|
|
7
|
+
{ "id": "C04", "name": "Pipe-to-Shell", "primitive": "DESTRUCTION", "severity": 9, "description": "Downloading and piping directly to a shell interpreter (curl | bash)" },
|
|
8
|
+
{ "id": "C05", "name": "Privilege Escalation", "primitive": "ESCALATION", "severity": 8, "description": "Commands that elevate privileges (sudo, chmod u+s, setuid)" },
|
|
9
|
+
{ "id": "C06", "name": "Persistence via Cron", "primitive": "PERSISTENCE", "severity": 7, "description": "Installing cron jobs for persistent execution" },
|
|
10
|
+
{ "id": "C07", "name": "Persistence via Shell Config", "primitive": "PERSISTENCE", "severity": 6, "description": "Modifying shell startup files (.bashrc, .zshrc, .profile)" },
|
|
11
|
+
{ "id": "C08", "name": "Lateral Movement", "primitive": "ESCALATION", "severity": 6, "description": "SSH, network scanning, or probing internal infrastructure" },
|
|
12
|
+
{ "id": "C09", "name": "Fork Bomb", "primitive": "DESTRUCTION", "severity": 9, "description": "Self-replicating process that exhausts system resources" },
|
|
13
|
+
{ "id": "C10", "name": "Environment Poisoning", "primitive": "PERSISTENCE", "severity": 6, "description": "Manipulating PATH, LD_PRELOAD, or other environment variables" },
|
|
14
|
+
{ "id": "C11", "name": "Git Hook Injection", "primitive": "PERSISTENCE", "severity": 6, "description": "Writing malicious scripts to .git/hooks/" },
|
|
15
|
+
{ "id": "C12", "name": "History Tampering", "primitive": "MANIPULATION", "severity": 4, "description": "Clearing or disabling command history to hide activity" },
|
|
16
|
+
{ "id": "C13", "name": "Encoded/Obfuscated Command", "primitive": "MANIPULATION", "severity": 8, "description": "Using base64, eval, or other encoding to hide command intent" },
|
|
17
|
+
{ "id": "C14", "name": "Variable Expansion Risk", "primitive": "DESTRUCTION", "severity": 7, "description": "Commands where empty variable expansion could cause destructive behavior" },
|
|
18
|
+
{ "id": "C15", "name": "Process Injection", "primitive": "ESCALATION", "severity": 8, "description": "Attaching to running processes via gdb, ptrace, or LD_PRELOAD" },
|
|
19
|
+
{ "id": "C16", "name": "Disk Filling", "primitive": "DESTRUCTION", "severity": 5, "description": "Commands that fill disk space (dd with large count to files)" },
|
|
20
|
+
{ "id": "C17", "name": "Network Listener", "primitive": "ESCALATION", "severity": 5, "description": "Opening network listeners (nc -l, python http.server, socat)" },
|
|
21
|
+
{ "id": "C18", "name": "Credential Harvesting", "primitive": "EXFILTRATION", "severity": 8, "description": "Reading sensitive files (.ssh/id_rsa, /etc/shadow, .env, *.pem)" },
|
|
22
|
+
{ "id": "C19", "name": "Container Escape", "primitive": "ESCALATION", "severity": 9, "description": "Escaping container isolation (--privileged, nsenter, --pid=host)" },
|
|
23
|
+
{ "id": "C20", "name": "Package Manager Abuse", "primitive": "DESTRUCTION", "severity": 3, "description": "Running package managers that may execute arbitrary install scripts" }
|
|
24
|
+
],
|
|
25
|
+
"destructiveCommands": ["rm", "rmdir", "mkfs", "dd", "shred", "wipefs", "fdisk", "parted", "truncate"],
|
|
26
|
+
"destructiveFlags": {
|
|
27
|
+
"rm": ["-rf", "-fr", "-r", "--recursive", "--no-preserve-root"],
|
|
28
|
+
"chmod": ["777", "000", "a+rwx"],
|
|
29
|
+
"chown": ["-R"],
|
|
30
|
+
"dd": ["of=/dev/"]
|
|
31
|
+
},
|
|
32
|
+
"criticalPaths": ["/", "/etc", "/boot", "/usr", "/var", "/sys", "/proc", "/dev", "/bin", "/sbin", "/lib", "/root", "/home"],
|
|
33
|
+
"exfiltrationCommands": ["curl", "wget", "nc", "ncat", "scp", "rsync", "ftp", "sftp"],
|
|
34
|
+
"exfiltrationPatterns": [">/dev/tcp/", "| curl", "| wget", "| nc ", "-d @", "--data-binary @", "--upload-file", "-T "],
|
|
35
|
+
"reverseShellPatterns": ["/dev/tcp/", "mkfifo", "0>&1", "bash -i", "exec 5<>", "0<&196", "/dev/udp/"],
|
|
36
|
+
"privilegeEscalation": ["sudo", "doas", "pkexec", "chmod u+s", "setuid"],
|
|
37
|
+
"persistenceTargets": [".bashrc", ".zshrc", ".profile", ".bash_profile", ".bash_login", "crontab", ".git/hooks/", "/etc/cron"],
|
|
38
|
+
"networkCommands": ["ssh", "nmap", "ping", "traceroute", "netcat", "nc", "socat"],
|
|
39
|
+
"containerEscapePatterns": ["--privileged", "nsenter", "--pid=host", "-v /:/host", "--cap-add=SYS_ADMIN"],
|
|
40
|
+
"packageManagers": ["npm", "pip", "pip3", "gem", "cargo", "go install", "yarn", "pnpm"],
|
|
41
|
+
"encodingCommands": ["base64", "xxd", "openssl enc"],
|
|
42
|
+
"pipeToShell": ["| bash", "| sh", "| zsh", "| dash", "| source"],
|
|
43
|
+
"safeCommands": ["ls", "cat", "echo", "pwd", "whoami", "date", "head", "tail", "grep", "find", "wc", "sort", "uniq", "diff", "less", "more", "man", "which", "type", "file", "stat", "du", "df", "uname", "env", "printenv", "id", "groups", "ps", "top", "htop", "cd", "mkdir", "touch", "cp", "mv", "ln", "readlink", "basename", "dirname", "realpath", "git", "node", "python", "python3", "ruby", "java", "go", "rustc", "tsc", "npx", "pnpm", "yarn", "npm", "pip", "pip3", "brew", "apt", "test", "true", "false", "seq", "tr", "cut", "paste", "tee", "xargs", "yes", "sleep", "clear", "reset"]
|
|
44
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2026.02.21",
|
|
3
|
+
"threats": [
|
|
4
|
+
{ "id": "FR01", "name": "SSH Key Access", "primitive": "EXFILTRATION", "severity": 9, "description": "Reading SSH private keys enables unauthorized remote access" },
|
|
5
|
+
{ "id": "FR02", "name": "System Credential Access", "primitive": "EXFILTRATION", "severity": 9, "description": "Reading system credential files like /etc/shadow" },
|
|
6
|
+
{ "id": "FR03", "name": "TLS Private Key Access", "primitive": "EXFILTRATION", "severity": 7, "description": "Reading TLS/SSL private keys (.pem, .key, .p12)" },
|
|
7
|
+
{ "id": "FR04", "name": "Cloud Credential Access", "primitive": "EXFILTRATION", "severity": 8, "description": "Reading cloud provider credential files (AWS, GCP, Azure, Docker, K8s)" },
|
|
8
|
+
{ "id": "FR05", "name": "Environment File Access", "primitive": "EXFILTRATION", "severity": 7, "description": "Reading .env files containing API keys and secrets" },
|
|
9
|
+
{ "id": "FR06", "name": "Application Credential Access", "primitive": "EXFILTRATION", "severity": 6, "description": "Reading application-specific credential or config files" },
|
|
10
|
+
{ "id": "FR07", "name": "System Info Disclosure", "primitive": "EXFILTRATION", "severity": 4, "description": "Reading system configuration files that reveal infrastructure details" },
|
|
11
|
+
{ "id": "FR08", "name": "Shell History Access", "primitive": "EXFILTRATION", "severity": 4, "description": "Reading shell history files which may contain secrets" },
|
|
12
|
+
{ "id": "FR09", "name": "Process Environment Access", "primitive": "EXFILTRATION", "severity": 5, "description": "Reading /proc environment data which may contain secrets" },
|
|
13
|
+
{ "id": "FR10", "name": "Browser Data Access", "primitive": "EXFILTRATION", "severity": 6, "description": "Reading browser profiles, cookies, stored passwords" }
|
|
14
|
+
],
|
|
15
|
+
"criticalPaths": [
|
|
16
|
+
{ "pattern": "~/.ssh/id_rsa", "score": 9, "threatId": "FR01", "reason": "SSH RSA private key", "matchType": "exact" },
|
|
17
|
+
{ "pattern": "~/.ssh/id_ed25519", "score": 9, "threatId": "FR01", "reason": "SSH Ed25519 private key", "matchType": "exact" },
|
|
18
|
+
{ "pattern": "~/.ssh/id_ecdsa", "score": 9, "threatId": "FR01", "reason": "SSH ECDSA private key", "matchType": "exact" },
|
|
19
|
+
{ "pattern": "~/.ssh/id_dsa", "score": 9, "threatId": "FR01", "reason": "SSH DSA private key", "matchType": "exact" },
|
|
20
|
+
{ "pattern": "/etc/shadow", "score": 9, "threatId": "FR02", "reason": "System password hashes", "matchType": "exact" },
|
|
21
|
+
{ "pattern": "/etc/master.passwd", "score": 9, "threatId": "FR02", "reason": "BSD system password hashes", "matchType": "exact" },
|
|
22
|
+
{ "pattern": "/etc/gshadow", "score": 9, "threatId": "FR02", "reason": "Group password hashes", "matchType": "exact" },
|
|
23
|
+
{ "pattern": "/etc/sudoers", "score": 8, "threatId": "FR02", "reason": "Sudo configuration reveals privilege structure", "matchType": "exact" }
|
|
24
|
+
],
|
|
25
|
+
"highPaths": [
|
|
26
|
+
{ "pattern": "~/.aws/credentials", "score": 8, "threatId": "FR04", "reason": "AWS credentials file", "matchType": "exact" },
|
|
27
|
+
{ "pattern": "~/.aws/config", "score": 5, "threatId": "FR04", "reason": "AWS configuration file", "matchType": "exact" },
|
|
28
|
+
{ "pattern": "~/.gcloud/credentials.db", "score": 8, "threatId": "FR04", "reason": "GCP credentials database", "matchType": "exact" },
|
|
29
|
+
{ "pattern": "~/.config/gcloud/", "score": 7, "threatId": "FR04", "reason": "GCP configuration directory", "matchType": "prefix" },
|
|
30
|
+
{ "pattern": "~/.azure/", "score": 7, "threatId": "FR04", "reason": "Azure credentials directory", "matchType": "prefix" },
|
|
31
|
+
{ "pattern": "~/.docker/config.json", "score": 7, "threatId": "FR04", "reason": "Docker registry credentials", "matchType": "exact" },
|
|
32
|
+
{ "pattern": "~/.kube/config", "score": 7, "threatId": "FR04", "reason": "Kubernetes cluster credentials", "matchType": "exact" },
|
|
33
|
+
{ "pattern": ".env", "score": 7, "threatId": "FR05", "reason": "Environment file with secrets", "matchType": "basename" },
|
|
34
|
+
{ "pattern": ".env.local", "score": 7, "threatId": "FR05", "reason": "Local environment file with secrets", "matchType": "basename" },
|
|
35
|
+
{ "pattern": ".env.production", "score": 7, "threatId": "FR05", "reason": "Production environment file with secrets", "matchType": "basename" },
|
|
36
|
+
{ "pattern": "~/.gnupg/", "score": 7, "threatId": "FR06", "reason": "GPG keys and configuration", "matchType": "prefix" },
|
|
37
|
+
{ "pattern": "~/.netrc", "score": 6, "threatId": "FR06", "reason": "Network credentials file", "matchType": "exact" },
|
|
38
|
+
{ "pattern": "~/.npmrc", "score": 5, "threatId": "FR06", "reason": "NPM credentials (may contain auth tokens)", "matchType": "exact" },
|
|
39
|
+
{ "pattern": "~/.pypirc", "score": 5, "threatId": "FR06", "reason": "PyPI credentials", "matchType": "exact" }
|
|
40
|
+
],
|
|
41
|
+
"mediumPaths": [
|
|
42
|
+
{ "pattern": "/etc/passwd", "score": 4, "threatId": "FR07", "reason": "System user list (no hashes but reveals usernames)", "matchType": "exact" },
|
|
43
|
+
{ "pattern": "/etc/hosts", "score": 3, "threatId": "FR07", "reason": "Host resolution configuration", "matchType": "exact" },
|
|
44
|
+
{ "pattern": "/etc/resolv.conf", "score": 3, "threatId": "FR07", "reason": "DNS resolver configuration", "matchType": "exact" },
|
|
45
|
+
{ "pattern": "~/.bash_history", "score": 4, "threatId": "FR08", "reason": "Bash command history (may contain secrets)", "matchType": "exact" },
|
|
46
|
+
{ "pattern": "~/.zsh_history", "score": 4, "threatId": "FR08", "reason": "Zsh command history (may contain secrets)", "matchType": "exact" },
|
|
47
|
+
{ "pattern": "~/.sh_history", "score": 4, "threatId": "FR08", "reason": "Shell history (may contain secrets)", "matchType": "exact" },
|
|
48
|
+
{ "pattern": "~/.node_repl_history", "score": 3, "threatId": "FR08", "reason": "Node.js REPL history", "matchType": "exact" },
|
|
49
|
+
{ "pattern": "~/.python_history", "score": 3, "threatId": "FR08", "reason": "Python REPL history", "matchType": "exact" },
|
|
50
|
+
{ "pattern": "/proc/self/environ", "score": 5, "threatId": "FR09", "reason": "Process environment variables", "matchType": "exact" },
|
|
51
|
+
{ "pattern": "/proc/self/cmdline", "score": 3, "threatId": "FR09", "reason": "Process command line arguments", "matchType": "exact" },
|
|
52
|
+
{ "pattern": "/proc/", "score": 3, "threatId": "FR09", "reason": "Process information", "matchType": "prefix" }
|
|
53
|
+
],
|
|
54
|
+
"sensitiveExtensions": [
|
|
55
|
+
{ "extension": ".pem", "score": 7, "threatId": "FR03", "reason": "PEM certificate/key file" },
|
|
56
|
+
{ "extension": ".key", "score": 7, "threatId": "FR03", "reason": "Private key file" },
|
|
57
|
+
{ "extension": ".p12", "score": 7, "threatId": "FR03", "reason": "PKCS#12 certificate bundle" },
|
|
58
|
+
{ "extension": ".pfx", "score": 7, "threatId": "FR03", "reason": "PFX certificate bundle" },
|
|
59
|
+
{ "extension": ".jks", "score": 6, "threatId": "FR03", "reason": "Java KeyStore file" },
|
|
60
|
+
{ "extension": ".keystore", "score": 6, "threatId": "FR03", "reason": "Keystore file" }
|
|
61
|
+
],
|
|
62
|
+
"browserDataPaths": [
|
|
63
|
+
{ "pattern": "Library/Application Support/Google/Chrome/", "score": 7, "threatId": "FR10", "reason": "Chrome browser data (macOS)", "matchType": "contains" },
|
|
64
|
+
{ "pattern": ".config/google-chrome/", "score": 7, "threatId": "FR10", "reason": "Chrome browser data (Linux)", "matchType": "contains" },
|
|
65
|
+
{ "pattern": "AppData/Local/Google/Chrome/", "score": 7, "threatId": "FR10", "reason": "Chrome browser data (Windows)", "matchType": "contains" },
|
|
66
|
+
{ "pattern": ".mozilla/firefox/", "score": 7, "threatId": "FR10", "reason": "Firefox browser data", "matchType": "contains" },
|
|
67
|
+
{ "pattern": "Library/Application Support/Firefox/", "score": 7, "threatId": "FR10", "reason": "Firefox browser data (macOS)", "matchType": "contains" },
|
|
68
|
+
{ "pattern": "Library/Safari/", "score": 6, "threatId": "FR10", "reason": "Safari browser data", "matchType": "contains" },
|
|
69
|
+
{ "pattern": "Login Data", "score": 5, "threatId": "FR10", "reason": "Browser stored passwords", "matchType": "basename" },
|
|
70
|
+
{ "pattern": "Cookies", "score": 5, "threatId": "FR10", "reason": "Browser cookies", "matchType": "basename" }
|
|
71
|
+
],
|
|
72
|
+
"safePaths": [
|
|
73
|
+
"src/", "lib/", "test/", "tests/", "docs/", "doc/", "build/", "dist/",
|
|
74
|
+
"node_modules/", "vendor/", "public/", "static/", "assets/", "scripts/",
|
|
75
|
+
"README", "LICENSE", "CHANGELOG", "package.json", "tsconfig.json",
|
|
76
|
+
"Cargo.toml", "go.mod", "pom.xml", "Gemfile", "requirements.txt"
|
|
77
|
+
],
|
|
78
|
+
"safeExtensions": [
|
|
79
|
+
".ts", ".js", ".tsx", ".jsx", ".py", ".rb", ".go", ".rs", ".java",
|
|
80
|
+
".kt", ".swift", ".c", ".cpp", ".h", ".cs", ".php", ".html", ".css",
|
|
81
|
+
".scss", ".less", ".json", ".yaml", ".yml", ".toml", ".xml", ".sql",
|
|
82
|
+
".md", ".txt", ".csv", ".svg", ".png", ".jpg", ".jpeg", ".gif",
|
|
83
|
+
".ico", ".woff", ".woff2", ".ttf", ".eot", ".lock", ".map"
|
|
84
|
+
]
|
|
85
|
+
}
|