@skillsmith/core 0.11.3 → 0.11.4
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 +21 -9
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/logging/logger.test.js +57 -0
- package/dist/src/logging/logger.test.js.map +1 -1
- package/dist/src/logging/rotation.d.ts +27 -2
- package/dist/src/logging/rotation.d.ts.map +1 -1
- package/dist/src/logging/rotation.js +44 -3
- package/dist/src/logging/rotation.js.map +1 -1
- package/dist/src/logging/rotation.test.js +69 -0
- package/dist/src/logging/rotation.test.js.map +1 -1
- package/dist/src/logging/types.d.ts +8 -2
- package/dist/src/logging/types.d.ts.map +1 -1
- package/dist/src/security/index.d.ts +2 -1
- package/dist/src/security/index.d.ts.map +1 -1
- package/dist/src/security/index.js +3 -0
- package/dist/src/security/index.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.d.ts +2 -2
- package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.evidence.d.ts +76 -0
- package/dist/src/security/scanner/SecurityScanner.evidence.d.ts.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.evidence.js +176 -0
- package/dist/src/security/scanner/SecurityScanner.evidence.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.exec.d.ts +8 -1
- package/dist/src/security/scanner/SecurityScanner.exec.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.exec.js +58 -2
- package/dist/src/security/scanner/SecurityScanner.exec.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.helpers.d.ts +35 -10
- package/dist/src/security/scanner/SecurityScanner.helpers.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.helpers.js +106 -59
- package/dist/src/security/scanner/SecurityScanner.helpers.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.js +41 -13
- package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.pii.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.pii.js +23 -1
- package/dist/src/security/scanner/SecurityScanner.pii.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.js +15 -3
- package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.ssrf.d.ts +11 -1
- package/dist/src/security/scanner/SecurityScanner.ssrf.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.ssrf.js +18 -7
- package/dist/src/security/scanner/SecurityScanner.ssrf.js.map +1 -1
- package/dist/src/security/scanner/index.d.ts +3 -3
- package/dist/src/security/scanner/index.d.ts.map +1 -1
- package/dist/src/security/scanner/index.js +5 -2
- package/dist/src/security/scanner/index.js.map +1 -1
- package/dist/src/security/scanner/patterns.d.ts +41 -14
- package/dist/src/security/scanner/patterns.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.jailbreak.d.ts +41 -0
- package/dist/src/security/scanner/patterns.jailbreak.d.ts.map +1 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.d.ts +35 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.d.ts.map +1 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.js +119 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.js.map +1 -0
- package/dist/src/security/scanner/patterns.jailbreak.js +370 -0
- package/dist/src/security/scanner/patterns.jailbreak.js.map +1 -0
- package/dist/src/security/scanner/patterns.js +101 -82
- package/dist/src/security/scanner/patterns.js.map +1 -1
- package/dist/src/security/scanner/patterns.scope.d.ts +62 -0
- package/dist/src/security/scanner/patterns.scope.d.ts.map +1 -0
- package/dist/src/security/scanner/patterns.scope.js +207 -0
- package/dist/src/security/scanner/patterns.scope.js.map +1 -0
- package/dist/src/security/scanner/regex-utils.d.ts +20 -0
- package/dist/src/security/scanner/regex-utils.d.ts.map +1 -1
- package/dist/src/security/scanner/regex-utils.js +20 -0
- package/dist/src/security/scanner/regex-utils.js.map +1 -1
- package/dist/src/security/scanner/types.d.ts +35 -0
- package/dist/src/security/scanner/types.d.ts.map +1 -1
- package/dist/src/services/skill-installation.io.d.ts.map +1 -1
- package/dist/src/services/skill-installation.io.js +12 -1
- package/dist/src/services/skill-installation.io.js.map +1 -1
- package/dist/src/sync/inventory-collector.d.ts.map +1 -1
- package/dist/src/sync/inventory-collector.js +2 -2
- package/dist/src/sync/inventory-collector.js.map +1 -1
- package/dist/tests/SecurityScanner.ai-defence.test.js +32 -7
- package/dist/tests/SecurityScanner.ai-defence.test.js.map +1 -1
- package/dist/tests/SecurityScanner.exec.test.js +79 -0
- package/dist/tests/SecurityScanner.exec.test.js.map +1 -1
- package/dist/tests/security/ContinuousSecurity.performance.test.js +6 -0
- package/dist/tests/security/ContinuousSecurity.performance.test.js.map +1 -1
- package/dist/tests/security/ContinuousSecurity.test.js +15 -0
- package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
- package/dist/tests/security/ad-crlf-injection.test.d.ts +18 -0
- package/dist/tests/security/ad-crlf-injection.test.d.ts.map +1 -0
- package/dist/tests/security/ad-crlf-injection.test.js +150 -0
- package/dist/tests/security/ad-crlf-injection.test.js.map +1 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.d.ts +25 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.d.ts.map +1 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.js +138 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.js.map +1 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.d.ts +15 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.d.ts.map +1 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.js +60 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.js.map +1 -0
- package/dist/tests/security/pattern-scope.test.d.ts +17 -0
- package/dist/tests/security/pattern-scope.test.d.ts.map +1 -0
- package/dist/tests/security/pattern-scope.test.js +128 -0
- package/dist/tests/security/pattern-scope.test.js.map +1 -0
- package/dist/tests/security/pii-detection.test.js +39 -0
- package/dist/tests/security/pii-detection.test.js.map +1 -1
- package/dist/tests/security/scanner-evidence-tiers.test.d.ts +30 -0
- package/dist/tests/security/scanner-evidence-tiers.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-evidence-tiers.test.js +258 -0
- package/dist/tests/security/scanner-evidence-tiers.test.js.map +1 -0
- package/dist/tests/security/scanner-privesc-severity.test.d.ts +23 -0
- package/dist/tests/security/scanner-privesc-severity.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-privesc-severity.test.js +43 -0
- package/dist/tests/security/scanner-privesc-severity.test.js.map +1 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.d.ts +20 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.js +71 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.js.map +1 -0
- package/dist/tests/security/scanner-regression-guard.test.d.ts +24 -0
- package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -1
- package/dist/tests/security/scanner-regression-guard.test.js +59 -3
- package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
- package/dist/tests/security/scanner-ssrf-word-boundary.test.d.ts +19 -0
- package/dist/tests/security/scanner-ssrf-word-boundary.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-ssrf-word-boundary.test.js +65 -0
- package/dist/tests/security/scanner-ssrf-word-boundary.test.js.map +1 -0
- package/dist/tests/security.test.js +11 -2
- package/dist/tests/security.test.js.map +1 -1
- package/dist/tests/skill-scanner/allowlist.test.js +15 -7
- package/dist/tests/skill-scanner/allowlist.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.io.test.js +54 -1
- package/dist/tests/unit/services/skill-installation.io.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityScanner.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAmB,UAAU,EAAE,cAAc,EAAqB,MAAM,YAAY,CAAA;AAUhG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC/D,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"SecurityScanner.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAmB,UAAU,EAAE,cAAc,EAAqB,MAAM,YAAY,CAAA;AAUhG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC/D,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAEnB,MAAM,8BAA8B,CAAA;AAGrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AA0B5D,OAAO,EACL,aAAa,EACb,OAAO,EACP,mBAAmB,EACnB,SAAS,EACV,MAAM,iCAAiC,CAAA;AAGxC,OAAO,EACL,WAAW,EACX,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,GACnB,CAAA;AACD,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAC3B,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,CAAA;AAEjE,qBAAa,eAAe;IAC1B,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,aAAa,CAAQ;gBAEjB,OAAO,GAAE,cAAmB;IAOxC,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,QAAQ;IAmBhB,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,sBAAsB;IA6D9B,OAAO,CAAC,4BAA4B;IAkBpC,0EAA0E;IAC1E,kBAAkB,4BAAqB;IAEvC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU;IA2FlD,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOpC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAItC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKxC,MAAM,CAAC,aAAa,uBAAgB;IACpC,MAAM,CAAC,OAAO,iBAAU;IACxB,MAAM,CAAC,mBAAmB,6BAAsB;IAChD,MAAM,CAAC,SAAS,mBAAY;CAC7B;AAED,eAAe,eAAe,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Scanner — evidence-tier severity resolution (SMI-5876)
|
|
3
|
+
* @module @skillsmith/core/security/scanner/SecurityScanner.evidence
|
|
4
|
+
*
|
|
5
|
+
* Turns a pattern's `EvidenceType` (classified in
|
|
6
|
+
* `patterns.jailbreak.evidence.ts`'s `EVIDENCE_TYPE_BY_PATTERN`, SMI-5881)
|
|
7
|
+
* plus documentation context into a severity/confidence pair, and provides
|
|
8
|
+
* the corroboration escalation that lifts a `mention`-tier finding when it
|
|
9
|
+
* co-occurs with a genuinely dangerous non-documentation signal elsewhere in
|
|
10
|
+
* the same scan.
|
|
11
|
+
*/
|
|
12
|
+
import type { EvidenceType, SecurityFinding, SecuritySeverity, FindingConfidence } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Classify a pattern's evidence tier by object identity. Unmapped patterns
|
|
15
|
+
* (i.e. a pattern added to JAILBREAK_PATTERNS/AI_DEFENCE_PATTERNS without an
|
|
16
|
+
* `EVIDENCE_TYPE_BY_PATTERN` entry) default to `imperative_instruction` —
|
|
17
|
+
* fail-closed: forgetting to classify a new pattern makes it the STRONGEST
|
|
18
|
+
* tier, never the weakest, so a missed classification can never silently
|
|
19
|
+
* soften detection.
|
|
20
|
+
*/
|
|
21
|
+
export declare function classifyEvidence(p: RegExp): EvidenceType;
|
|
22
|
+
/**
|
|
23
|
+
* Relative strength ordering used by the merge-loop in
|
|
24
|
+
* `SecurityScanner.helpers.ts` to pick the strongest evidence per line across
|
|
25
|
+
* both the multi-line and single-line scan passes. `imperative_instruction`,
|
|
26
|
+
* `instruction_override`, and `state_assertion` are equal rank — the
|
|
27
|
+
* severity table below treats them identically, and none needs to out-rank
|
|
28
|
+
* the others. `state_assertion` (SMI-5876 design-pass follow-up) is a
|
|
29
|
+
* distinct machine-readable REASON CODE for a declarative jailbroken-state
|
|
30
|
+
* assertion ("Jailbreak activated") rather than a directive aimed at the
|
|
31
|
+
* model — same severity tuple, different diagnostic label.
|
|
32
|
+
*/
|
|
33
|
+
export declare const EVIDENCE_RANK: Record<EvidenceType, number>;
|
|
34
|
+
/** The highest rank in `EVIDENCE_RANK` — once reached, no later pattern on the same line can beat it. */
|
|
35
|
+
export declare const MAX_EVIDENCE_RANK = 2;
|
|
36
|
+
/**
|
|
37
|
+
* Severity/confidence decision table (SMI-5876 design §4.1). Doc-context
|
|
38
|
+
* confidence for the directive tiers is `medium`, not `low` — `low` would be
|
|
39
|
+
* self-contradictory next to a still-failing severity (it would also cut the
|
|
40
|
+
* risk-score weight to 0.3x, which is not the intent for a directive payload
|
|
41
|
+
* that merely happens to sit inside a fenced example).
|
|
42
|
+
*/
|
|
43
|
+
export declare const EVIDENCE_SEVERITY_TABLE: Record<EvidenceType, {
|
|
44
|
+
doc: {
|
|
45
|
+
severity: SecuritySeverity;
|
|
46
|
+
confidence: FindingConfidence;
|
|
47
|
+
};
|
|
48
|
+
nonDoc: {
|
|
49
|
+
severity: SecuritySeverity;
|
|
50
|
+
confidence: FindingConfidence;
|
|
51
|
+
};
|
|
52
|
+
}>;
|
|
53
|
+
/** Resolve the severity/confidence pair for an evidence tier + documentation context. */
|
|
54
|
+
export declare function resolveEvidenceSeverity(tier: EvidenceType, inDocumentationContext: boolean): {
|
|
55
|
+
severity: SecuritySeverity;
|
|
56
|
+
confidence: FindingConfidence;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Escalate a `mention`-tier finding when an ALLOWLISTED non-documentation
|
|
60
|
+
* high/critical finding is ALSO present within `MAX_CORROBORATION_LINE_DISTANCE`
|
|
61
|
+
* lines in the same scan (SMI-5876 design §4.3, corrected post-implementation —
|
|
62
|
+
* see `CORROBORATING_SIGNALS`' doc comment for the denylist->allowlist fix and
|
|
63
|
+
* the locality-window rationale). Mutates findings in place, mirroring
|
|
64
|
+
* `escalateCodeExecution`'s mutation style (SecurityScanner.exec.ts).
|
|
65
|
+
*
|
|
66
|
+
* MUST run after `escalateCodeExecution` (SecurityScanner.ts's `scan()`) so a
|
|
67
|
+
* freshly-critical `code_execution` finding can itself serve as a
|
|
68
|
+
* corroborator. No feedback loop the other way: `CODE_EXECUTION_CO_OCCURRENCE`
|
|
69
|
+
* (SecurityScanner.exec.ts) contains only `data_exfiltration`,
|
|
70
|
+
* `privilege_escalation`, `sensitive_path`, and `obfuscated_directive` — never
|
|
71
|
+
* `jailbreak` or `ai_defence` — so lifting a mention here can never
|
|
72
|
+
* retroactively change `escalateCodeExecution`'s own decision (verified by
|
|
73
|
+
* reading SecurityScanner.exec.ts directly, SMI-5876 implementation).
|
|
74
|
+
*/
|
|
75
|
+
export declare function escalateCorroboratedMentions(findings: SecurityFinding[]): void;
|
|
76
|
+
//# sourceMappingURL=SecurityScanner.evidence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecurityScanner.evidence.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAEf,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,YAAY,CAAA;AAGnB;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,YAAY,CAExD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAMtD,CAAA;AAED,yGAAyG;AACzG,eAAO,MAAM,iBAAiB,IAAI,CAAA;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAC1C,YAAY,EACZ;IACE,GAAG,EAAE;QAAE,QAAQ,EAAE,gBAAgB,CAAC;QAAC,UAAU,EAAE,iBAAiB,CAAA;KAAE,CAAA;IAClE,MAAM,EAAE;QAAE,QAAQ,EAAE,gBAAgB,CAAC;QAAC,UAAU,EAAE,iBAAiB,CAAA;KAAE,CAAA;CACtE,CAwBF,CAAA;AAED,yFAAyF;AACzF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,YAAY,EAClB,sBAAsB,EAAE,OAAO,GAC9B;IAAE,QAAQ,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,iBAAiB,CAAA;CAAE,CAG/D;AA0DD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,IAAI,CA4B9E"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Scanner — evidence-tier severity resolution (SMI-5876)
|
|
3
|
+
* @module @skillsmith/core/security/scanner/SecurityScanner.evidence
|
|
4
|
+
*
|
|
5
|
+
* Turns a pattern's `EvidenceType` (classified in
|
|
6
|
+
* `patterns.jailbreak.evidence.ts`'s `EVIDENCE_TYPE_BY_PATTERN`, SMI-5881)
|
|
7
|
+
* plus documentation context into a severity/confidence pair, and provides
|
|
8
|
+
* the corroboration escalation that lifts a `mention`-tier finding when it
|
|
9
|
+
* co-occurs with a genuinely dangerous non-documentation signal elsewhere in
|
|
10
|
+
* the same scan.
|
|
11
|
+
*/
|
|
12
|
+
import { EVIDENCE_TYPE_BY_PATTERN } from './patterns.jailbreak.evidence.js';
|
|
13
|
+
/**
|
|
14
|
+
* Classify a pattern's evidence tier by object identity. Unmapped patterns
|
|
15
|
+
* (i.e. a pattern added to JAILBREAK_PATTERNS/AI_DEFENCE_PATTERNS without an
|
|
16
|
+
* `EVIDENCE_TYPE_BY_PATTERN` entry) default to `imperative_instruction` —
|
|
17
|
+
* fail-closed: forgetting to classify a new pattern makes it the STRONGEST
|
|
18
|
+
* tier, never the weakest, so a missed classification can never silently
|
|
19
|
+
* soften detection.
|
|
20
|
+
*/
|
|
21
|
+
export function classifyEvidence(p) {
|
|
22
|
+
return EVIDENCE_TYPE_BY_PATTERN.get(p) ?? 'imperative_instruction';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Relative strength ordering used by the merge-loop in
|
|
26
|
+
* `SecurityScanner.helpers.ts` to pick the strongest evidence per line across
|
|
27
|
+
* both the multi-line and single-line scan passes. `imperative_instruction`,
|
|
28
|
+
* `instruction_override`, and `state_assertion` are equal rank — the
|
|
29
|
+
* severity table below treats them identically, and none needs to out-rank
|
|
30
|
+
* the others. `state_assertion` (SMI-5876 design-pass follow-up) is a
|
|
31
|
+
* distinct machine-readable REASON CODE for a declarative jailbroken-state
|
|
32
|
+
* assertion ("Jailbreak activated") rather than a directive aimed at the
|
|
33
|
+
* model — same severity tuple, different diagnostic label.
|
|
34
|
+
*/
|
|
35
|
+
export const EVIDENCE_RANK = {
|
|
36
|
+
mention: 0,
|
|
37
|
+
role_turn_with_body: 1,
|
|
38
|
+
imperative_instruction: 2,
|
|
39
|
+
instruction_override: 2,
|
|
40
|
+
state_assertion: 2,
|
|
41
|
+
};
|
|
42
|
+
/** The highest rank in `EVIDENCE_RANK` — once reached, no later pattern on the same line can beat it. */
|
|
43
|
+
export const MAX_EVIDENCE_RANK = 2;
|
|
44
|
+
/**
|
|
45
|
+
* Severity/confidence decision table (SMI-5876 design §4.1). Doc-context
|
|
46
|
+
* confidence for the directive tiers is `medium`, not `low` — `low` would be
|
|
47
|
+
* self-contradictory next to a still-failing severity (it would also cut the
|
|
48
|
+
* risk-score weight to 0.3x, which is not the intent for a directive payload
|
|
49
|
+
* that merely happens to sit inside a fenced example).
|
|
50
|
+
*/
|
|
51
|
+
export const EVIDENCE_SEVERITY_TABLE = {
|
|
52
|
+
mention: {
|
|
53
|
+
nonDoc: { severity: 'low', confidence: 'low' },
|
|
54
|
+
doc: { severity: 'low', confidence: 'low' },
|
|
55
|
+
},
|
|
56
|
+
role_turn_with_body: {
|
|
57
|
+
nonDoc: { severity: 'high', confidence: 'high' },
|
|
58
|
+
doc: { severity: 'medium', confidence: 'medium' },
|
|
59
|
+
},
|
|
60
|
+
imperative_instruction: {
|
|
61
|
+
nonDoc: { severity: 'critical', confidence: 'high' },
|
|
62
|
+
doc: { severity: 'high', confidence: 'medium' },
|
|
63
|
+
},
|
|
64
|
+
instruction_override: {
|
|
65
|
+
nonDoc: { severity: 'critical', confidence: 'high' },
|
|
66
|
+
doc: { severity: 'high', confidence: 'medium' },
|
|
67
|
+
},
|
|
68
|
+
// SMI-5876 design-pass follow-up: same tuple as imperative_instruction —
|
|
69
|
+
// state_assertion is a distinct reason code, not a distinct severity tier.
|
|
70
|
+
state_assertion: {
|
|
71
|
+
nonDoc: { severity: 'critical', confidence: 'high' },
|
|
72
|
+
doc: { severity: 'high', confidence: 'medium' },
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
/** Resolve the severity/confidence pair for an evidence tier + documentation context. */
|
|
76
|
+
export function resolveEvidenceSeverity(tier, inDocumentationContext) {
|
|
77
|
+
const entry = EVIDENCE_SEVERITY_TABLE[tier];
|
|
78
|
+
return inDocumentationContext ? entry.doc : entry.nonDoc;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* SMI-5876 (post-implementation correction): corroborator eligibility is an
|
|
82
|
+
* ALLOWLIST of INSTRUCTION-BEARING attack categories, not a denylist of
|
|
83
|
+
* everything-except-self.
|
|
84
|
+
*
|
|
85
|
+
* The original design specified `type ∉ {jailbreak, ai_defence}`, reasoning only
|
|
86
|
+
* about same-category circularity. That is the classic denylist failure — it
|
|
87
|
+
* silently admits every category nobody considered. It admitted `pii`, whose
|
|
88
|
+
* plain-email pattern fires on the author-contact bullet that nearly every
|
|
89
|
+
* SKILL.md carries, so an unrelated `- Email: support@…` 74 lines away lifted a
|
|
90
|
+
* benign "jailbreak" mention to high in this repo's OWN bundled SKILL.md — one of
|
|
91
|
+
* SMI-5876's three acceptance fixtures.
|
|
92
|
+
*
|
|
93
|
+
* Both existing precedents here are allowlists: CODE_EXECUTION_CO_OCCURRENCE
|
|
94
|
+
* (SecurityScanner.exec.ts) and SUPPLY_CHAIN_CO_SIGNALS
|
|
95
|
+
* (SecurityScanner.hostile-update.ts). This restores that discipline.
|
|
96
|
+
*
|
|
97
|
+
* Inclusion rule — the category must be INSTRUCTION-BEARING (its patterns match
|
|
98
|
+
* an instruction to do something adversarial). Deliberately excluded:
|
|
99
|
+
* • `pii` / `sensitive_path` — REFERENCE-bearing. A contact email or a `.env`
|
|
100
|
+
* path says something about data hygiene, nothing about whether a jailbreak
|
|
101
|
+
* ATTEMPT is present.
|
|
102
|
+
* • `suspicious_pattern` — `eval(` / `child_process` are ordinary vocabulary in
|
|
103
|
+
* dev-tooling skills.
|
|
104
|
+
* • `social_engineering` / `prompt_leaking` — semantically ADJACENT to jailbreak;
|
|
105
|
+
* admitting them recreates the very circularity the self-exclusion prevents
|
|
106
|
+
* (a persona/roleplay skill would lift its own jailbreak mentions).
|
|
107
|
+
* • `typosquat` — a property of the skill NAME, not its content.
|
|
108
|
+
* • `url` — capped at medium, so it could never qualify anyway.
|
|
109
|
+
* • `jailbreak` / `ai_defence` — same-category self-lift (original exclusion).
|
|
110
|
+
*/
|
|
111
|
+
const CORROBORATING_SIGNALS = new Set([
|
|
112
|
+
'code_execution',
|
|
113
|
+
'obfuscated_directive',
|
|
114
|
+
'data_exfiltration',
|
|
115
|
+
'privilege_escalation',
|
|
116
|
+
'ssrf',
|
|
117
|
+
]);
|
|
118
|
+
/**
|
|
119
|
+
* Maximum line distance between a mention and its corroborator.
|
|
120
|
+
*
|
|
121
|
+
* Why a bounded window is NOT a bypass vector: corroboration is a risk-SCORE and
|
|
122
|
+
* hostile-update amplifier only — it can never flip `passed`, because any
|
|
123
|
+
* qualifying corroborator is itself high/critical and therefore already fails the
|
|
124
|
+
* scan on its own (`passed = !hasCritical && !hasHigh && !exceedsThreshold`). An
|
|
125
|
+
* attacker who separates the two signals to duck the window still fails on the
|
|
126
|
+
* corroborator alone; all they achieve is a slightly lower numeric score on a
|
|
127
|
+
* scan that already blocks.
|
|
128
|
+
*
|
|
129
|
+
* 40 lines comfortably spans a real payload block (persona preamble plus the
|
|
130
|
+
* instructions it sets up) while excluding the "unrelated finding in a different
|
|
131
|
+
* section of a long document" case that motivated this constraint.
|
|
132
|
+
*/
|
|
133
|
+
const MAX_CORROBORATION_LINE_DISTANCE = 40;
|
|
134
|
+
/**
|
|
135
|
+
* Escalate a `mention`-tier finding when an ALLOWLISTED non-documentation
|
|
136
|
+
* high/critical finding is ALSO present within `MAX_CORROBORATION_LINE_DISTANCE`
|
|
137
|
+
* lines in the same scan (SMI-5876 design §4.3, corrected post-implementation —
|
|
138
|
+
* see `CORROBORATING_SIGNALS`' doc comment for the denylist->allowlist fix and
|
|
139
|
+
* the locality-window rationale). Mutates findings in place, mirroring
|
|
140
|
+
* `escalateCodeExecution`'s mutation style (SecurityScanner.exec.ts).
|
|
141
|
+
*
|
|
142
|
+
* MUST run after `escalateCodeExecution` (SecurityScanner.ts's `scan()`) so a
|
|
143
|
+
* freshly-critical `code_execution` finding can itself serve as a
|
|
144
|
+
* corroborator. No feedback loop the other way: `CODE_EXECUTION_CO_OCCURRENCE`
|
|
145
|
+
* (SecurityScanner.exec.ts) contains only `data_exfiltration`,
|
|
146
|
+
* `privilege_escalation`, `sensitive_path`, and `obfuscated_directive` — never
|
|
147
|
+
* `jailbreak` or `ai_defence` — so lifting a mention here can never
|
|
148
|
+
* retroactively change `escalateCodeExecution`'s own decision (verified by
|
|
149
|
+
* reading SecurityScanner.exec.ts directly, SMI-5876 implementation).
|
|
150
|
+
*/
|
|
151
|
+
export function escalateCorroboratedMentions(findings) {
|
|
152
|
+
const corroborators = findings.filter((f) => (f.severity === 'high' || f.severity === 'critical') &&
|
|
153
|
+
f.inDocumentationContext !== true &&
|
|
154
|
+
CORROBORATING_SIGNALS.has(f.type) &&
|
|
155
|
+
typeof f.lineNumber === 'number');
|
|
156
|
+
if (corroborators.length === 0)
|
|
157
|
+
return;
|
|
158
|
+
for (const finding of findings) {
|
|
159
|
+
if (finding.evidenceType !== 'mention')
|
|
160
|
+
continue;
|
|
161
|
+
if (typeof finding.lineNumber !== 'number')
|
|
162
|
+
continue;
|
|
163
|
+
const corroborator = corroborators.find((c) => Math.abs(c.lineNumber - finding.lineNumber) <=
|
|
164
|
+
MAX_CORROBORATION_LINE_DISTANCE);
|
|
165
|
+
if (!corroborator)
|
|
166
|
+
continue;
|
|
167
|
+
const inDoc = finding.inDocumentationContext === true;
|
|
168
|
+
finding.severity = inDoc ? 'medium' : 'high';
|
|
169
|
+
finding.confidence = inDoc ? 'low' : 'medium';
|
|
170
|
+
finding.corroborated = true;
|
|
171
|
+
finding.message =
|
|
172
|
+
`Corroborated by a co-occurring non-documentation ${corroborator.type} ` +
|
|
173
|
+
`finding at line ${corroborator.lineNumber} — ${finding.message}`;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=SecurityScanner.evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecurityScanner.evidence.js","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAA;AAE3E;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAS;IACxC,OAAO,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,wBAAwB,CAAA;AACpE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,aAAa,GAAiC;IACzD,OAAO,EAAE,CAAC;IACV,mBAAmB,EAAE,CAAC;IACtB,sBAAsB,EAAE,CAAC;IACzB,oBAAoB,EAAE,CAAC;IACvB,eAAe,EAAE,CAAC;CACnB,CAAA;AAED,yGAAyG;AACzG,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAA;AAElC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAMhC;IACF,OAAO,EAAE;QACP,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;QAC9C,GAAG,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;KAC5C;IACD,mBAAmB,EAAE;QACnB,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE;QAChD,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE;KAClD;IACD,sBAAsB,EAAE;QACtB,MAAM,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE;QACpD,GAAG,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE;KAChD;IACD,oBAAoB,EAAE;QACpB,MAAM,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE;QACpD,GAAG,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE;KAChD;IACD,yEAAyE;IACzE,2EAA2E;IAC3E,eAAe,EAAE;QACf,MAAM,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE;QACpD,GAAG,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE;KAChD;CACF,CAAA;AAED,yFAAyF;AACzF,MAAM,UAAU,uBAAuB,CACrC,IAAkB,EAClB,sBAA+B;IAE/B,MAAM,KAAK,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IAC3C,OAAO,sBAAsB,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;AAC1D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,qBAAqB,GAAqC,IAAI,GAAG,CAAC;IACtE,gBAAgB;IAChB,sBAAsB;IACtB,mBAAmB;IACnB,sBAAsB;IACtB,MAAM;CACP,CAAC,CAAA;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,+BAA+B,GAAG,EAAE,CAAA;AAE1C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,4BAA4B,CAAC,QAA2B;IACtE,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC;QACpD,CAAC,CAAC,sBAAsB,KAAK,IAAI;QACjC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QACjC,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,CACnC,CAAA;IACD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAEtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS;YAAE,SAAQ;QAChD,IAAI,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ;YAAE,SAAQ;QACpD,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,CACrC,CAAC,CAAC,EAAE,EAAE,CACJ,IAAI,CAAC,GAAG,CAAE,CAAC,CAAC,UAAqB,GAAI,OAAO,CAAC,UAAqB,CAAC;YACnE,+BAA+B,CAClC,CAAA;QACD,IAAI,CAAC,YAAY;YAAE,SAAQ;QAE3B,MAAM,KAAK,GAAG,OAAO,CAAC,sBAAsB,KAAK,IAAI,CAAA;QACrD,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAA;QAC5C,OAAO,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAA;QAC7C,OAAO,CAAC,YAAY,GAAG,IAAI,CAAA;QAC3B,OAAO,CAAC,OAAO;YACb,oDAAoD,YAAY,CAAC,IAAI,GAAG;gBACxE,mBAAmB,YAAY,CAAC,UAAU,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;IACrE,CAAC;AACH,CAAC"}
|
|
@@ -55,9 +55,16 @@ export declare function scanObfuscatedDirective(content: string): SecurityFindin
|
|
|
55
55
|
/**
|
|
56
56
|
* Escalate the code_execution finding to CRITICAL when a NON-documentation
|
|
57
57
|
* high/critical exfiltration / privilege / credential-path / obfuscation signal
|
|
58
|
-
* is also present
|
|
58
|
+
* is also present WITHIN `MAX_CODE_EXECUTION_CO_SIGNAL_LINE_DISTANCE` lines
|
|
59
|
+
* (SMI-5880 — previously any distance qualified, so an unrelated finding in a
|
|
60
|
+
* different section of a long document escalated an unrelated code_execution
|
|
61
|
+
* finding). Mutates the finding in place. Requiring the co-signal to be
|
|
59
62
|
* non-documentation keeps legitimate security-research skills (whose examples
|
|
60
63
|
* live in fenced blocks) at MEDIUM.
|
|
64
|
+
*
|
|
65
|
+
* Runs BEFORE the sibling corroboration mechanism in `scan()` — see that
|
|
66
|
+
* function's doc comment (SecurityScanner.evidence.ts) for why the ordering is
|
|
67
|
+
* safe in both directions.
|
|
61
68
|
*/
|
|
62
69
|
export declare function escalateCodeExecution(findings: SecurityFinding[]): void;
|
|
63
70
|
//# sourceMappingURL=SecurityScanner.exec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityScanner.exec.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.exec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAuB,MAAM,YAAY,CAAA;AAGtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AA4B/D;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhD;AA0BD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,WAAW,EAAE,GAC3B,eAAe,EAAE,CA6BnB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CAuC1E;
|
|
1
|
+
{"version":3,"file":"SecurityScanner.exec.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.exec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAuB,MAAM,YAAY,CAAA;AAGtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AA4B/D;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhD;AA0BD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,WAAW,EAAE,GAC3B,eAAe,EAAE,CA6BnB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CAuC1E;AA8DD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,IAAI,CAiBvE"}
|
|
@@ -168,12 +168,67 @@ const CODE_EXECUTION_CO_OCCURRENCE = new Set([
|
|
|
168
168
|
'sensitive_path',
|
|
169
169
|
'obfuscated_directive',
|
|
170
170
|
]);
|
|
171
|
+
/**
|
|
172
|
+
* Maximum line distance between the `code_execution` finding and the co-signal
|
|
173
|
+
* that escalates it (SMI-5880). Before this bound, a co-signal ANYWHERE in the
|
|
174
|
+
* document — any distance, any unrelated section — escalated the single
|
|
175
|
+
* `code_execution` finding to critical.
|
|
176
|
+
*
|
|
177
|
+
* Why a bounded window is NOT a bypass vector: every eligible co-signal is
|
|
178
|
+
* already `high` or `critical`, and `scan()` (SecurityScanner.ts) computes
|
|
179
|
+
* `passed = !hasCritical && !hasHigh && !exceedsThreshold` across ALL findings
|
|
180
|
+
* with no locality filter and no documentation filter. A qualifying co-signal
|
|
181
|
+
* anywhere therefore forces `passed === false` on its own, BEFORE this function
|
|
182
|
+
* runs. Splitting the two signals to duck this window cannot turn a failing scan
|
|
183
|
+
* into a passing one; it changes only this finding's own label (medium vs
|
|
184
|
+
* critical) and the risk-score magnitude of a scan that already blocks.
|
|
185
|
+
* Hostile-update detection is likewise untouched: `detectSupplyChain()`
|
|
186
|
+
* (SecurityScanner.hostile-update.ts) pairs a NEW non-doc `code_execution` of ANY
|
|
187
|
+
* severity with a NEW non-doc high/critical co-signal at ANY distance, so a
|
|
188
|
+
* far-apart rug-pull still returns the `hostile` verdict and its supply-chain
|
|
189
|
+
* reason string.
|
|
190
|
+
*
|
|
191
|
+
* Deliberately the same 40 as the sibling corroboration mechanism's locality
|
|
192
|
+
* constant (SecurityScanner.evidence.ts) so the scanner has ONE locality model
|
|
193
|
+
* — but kept as its own constant, not imported: the two mechanisms are
|
|
194
|
+
* independently tunable, and the edge twins (SMI-5879) cannot import from core
|
|
195
|
+
* and must carry their own copy.
|
|
196
|
+
*/
|
|
197
|
+
const MAX_CODE_EXECUTION_CO_SIGNAL_LINE_DISTANCE = 40;
|
|
198
|
+
/**
|
|
199
|
+
* Locality gate for `escalateCodeExecution`. Fail-CLOSED on missing metadata:
|
|
200
|
+
* when either side has no `lineNumber` the distance is unknowable, and this
|
|
201
|
+
* subsystem's convention is that missing metadata must never SILENTLY weaken
|
|
202
|
+
* detection — cf. `classifyEvidence` (SecurityScanner.evidence.ts), whose
|
|
203
|
+
* unmapped-pattern default is the STRONGEST tier for exactly this reason. An
|
|
204
|
+
* unknowable distance therefore preserves the pre-SMI-5880 unbounded behavior for
|
|
205
|
+
* that pair rather than suppressing the co-signal.
|
|
206
|
+
*
|
|
207
|
+
* Unreachable through `scan()` today: `scanCodeExecution` above and every emitter
|
|
208
|
+
* of the four CODE_EXECUTION_CO_OCCURRENCE types set `lineNumber` unconditionally
|
|
209
|
+
* (the sensitive-path/data-exfiltration/privilege-escalation scanners in the
|
|
210
|
+
* scanners module, the chmod-compound detector, and `scanObfuscatedDirective`
|
|
211
|
+
* above). Kept as an explicit, directly-tested branch so a future detector that
|
|
212
|
+
* forgets `lineNumber` degrades safe instead of silently ceasing to escalate.
|
|
213
|
+
*/
|
|
214
|
+
function isWithinCoSignalWindow(codeExecLine, coSignalLine) {
|
|
215
|
+
if (typeof codeExecLine !== 'number' || typeof coSignalLine !== 'number')
|
|
216
|
+
return true;
|
|
217
|
+
return Math.abs(codeExecLine - coSignalLine) <= MAX_CODE_EXECUTION_CO_SIGNAL_LINE_DISTANCE;
|
|
218
|
+
}
|
|
171
219
|
/**
|
|
172
220
|
* Escalate the code_execution finding to CRITICAL when a NON-documentation
|
|
173
221
|
* high/critical exfiltration / privilege / credential-path / obfuscation signal
|
|
174
|
-
* is also present
|
|
222
|
+
* is also present WITHIN `MAX_CODE_EXECUTION_CO_SIGNAL_LINE_DISTANCE` lines
|
|
223
|
+
* (SMI-5880 — previously any distance qualified, so an unrelated finding in a
|
|
224
|
+
* different section of a long document escalated an unrelated code_execution
|
|
225
|
+
* finding). Mutates the finding in place. Requiring the co-signal to be
|
|
175
226
|
* non-documentation keeps legitimate security-research skills (whose examples
|
|
176
227
|
* live in fenced blocks) at MEDIUM.
|
|
228
|
+
*
|
|
229
|
+
* Runs BEFORE the sibling corroboration mechanism in `scan()` — see that
|
|
230
|
+
* function's doc comment (SecurityScanner.evidence.ts) for why the ordering is
|
|
231
|
+
* safe in both directions.
|
|
177
232
|
*/
|
|
178
233
|
export function escalateCodeExecution(findings) {
|
|
179
234
|
const codeExec = findings.find((f) => f.type === 'code_execution');
|
|
@@ -182,7 +237,8 @@ export function escalateCodeExecution(findings) {
|
|
|
182
237
|
const hasDangerousCoSignal = findings.some((f) => f !== codeExec &&
|
|
183
238
|
CODE_EXECUTION_CO_OCCURRENCE.has(f.type) &&
|
|
184
239
|
f.inDocumentationContext !== true &&
|
|
185
|
-
(f.severity === 'high' || f.severity === 'critical')
|
|
240
|
+
(f.severity === 'high' || f.severity === 'critical') &&
|
|
241
|
+
isWithinCoSignalWindow(codeExec.lineNumber, f.lineNumber));
|
|
186
242
|
if (hasDangerousCoSignal) {
|
|
187
243
|
codeExec.severity = 'critical';
|
|
188
244
|
codeExec.message = `Remote fetch piped to an interpreter, co-occurring with exfiltration/privilege/credential signals — likely supply-chain execution. ${codeExec.message}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityScanner.exec.js","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.exec.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SecurityScanner.exec.js","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Security Scanner Helper Functions
|
|
3
3
|
* @module @skillsmith/core/security/scanner/SecurityScanner.helpers
|
|
4
4
|
*/
|
|
5
|
-
import type { SecurityFinding, SecurityFindingType, RiskScoreBreakdown,
|
|
5
|
+
import type { SecurityFinding, SecurityFindingType, RiskScoreBreakdown, EvidenceType } from './types.js';
|
|
6
6
|
/**
|
|
7
7
|
* Context information for each line in markdown content
|
|
8
8
|
*/
|
|
@@ -21,12 +21,6 @@ export interface LineContext {
|
|
|
21
21
|
*/
|
|
22
22
|
inFrontmatter: boolean;
|
|
23
23
|
}
|
|
24
|
-
/**
|
|
25
|
-
* SMI-1532: Check if a regex pattern requires multi-line matching
|
|
26
|
-
* Patterns that contain newline/carriage-return characters or start with
|
|
27
|
-
* multi-line anchors need to be tested against full content, not line-by-line.
|
|
28
|
-
*/
|
|
29
|
-
export declare function isMultilinePattern(pattern: RegExp): boolean;
|
|
30
24
|
/**
|
|
31
25
|
* Analyze markdown content and return context for each line
|
|
32
26
|
* Used to reduce false positives in documentation/examples
|
|
@@ -59,14 +53,45 @@ interface MultilineScanConfig {
|
|
|
59
53
|
type: SecurityFindingType;
|
|
60
54
|
messagePrefix: string;
|
|
61
55
|
patterns: RegExp[];
|
|
62
|
-
/**
|
|
63
|
-
|
|
56
|
+
/**
|
|
57
|
+
* SMI-5876: replaces the flat `[docContext, normal]` severity pair — returns
|
|
58
|
+
* the evidence tier for a given pattern (by object identity) so
|
|
59
|
+
* severity/confidence can be resolved per-line via `resolveEvidenceSeverity`
|
|
60
|
+
* once the strongest tier for that line is known.
|
|
61
|
+
*/
|
|
62
|
+
classify: (pattern: RegExp) => EvidenceType;
|
|
64
63
|
}
|
|
65
64
|
/**
|
|
66
65
|
* Scan content for patterns that may span multiple lines.
|
|
67
66
|
* Multi-line patterns are tested against full content; single-line patterns per-line.
|
|
67
|
+
*
|
|
68
|
+
* SMI-5876: patterns within a single category (jailbreak / ai_defence) can now
|
|
69
|
+
* carry DIFFERENT evidence tiers (a bare "jailbreak" mention vs. an explicit
|
|
70
|
+
* "ignore all previous instructions" override), so array-declaration order is
|
|
71
|
+
* no longer sufficient to decide which match wins on a line where multiple
|
|
72
|
+
* patterns fire — the STRONGEST evidence tier per line wins, computed via a
|
|
73
|
+
* merge across both passes (`bestByLine`), not "first match, in array order."
|
|
74
|
+
*
|
|
75
|
+
* Two hazards this closes (see the SMI-5876 design doc §5 for the full
|
|
76
|
+
* argument):
|
|
77
|
+
* Hazard A — pass 2 used to `break` on the FIRST matching pattern
|
|
78
|
+
* regardless of tier, so a weaker mention declared earlier in the array
|
|
79
|
+
* could shadow a stronger directive declared later on the same line.
|
|
80
|
+
* Hazard B — a multiline pattern match used to suppress ALL single-line
|
|
81
|
+
* patterns on that line (`flaggedLines`), so a mention-tier multiline
|
|
82
|
+
* match could hide a directive-tier single-line match on the same line.
|
|
83
|
+
* `bestByLine` SEEDS pass 2 with pass 1's result instead of skipping the
|
|
84
|
+
* line outright, so pass 2 can still find something stronger.
|
|
85
|
+
*/
|
|
86
|
+
export declare function scanPatternsWithMultilineSupport(content: string, config: MultilineScanConfig, lineContexts?: LineContext[],
|
|
87
|
+
/**
|
|
88
|
+
* SMI-5881: explicit cap (UTF-16 code units) for the pass-1 full-content
|
|
89
|
+
* regex scan — `Math.min(MAX_CONTENT_LENGTH_FOR_REGEX, maxContentLength)`,
|
|
90
|
+
* computed once by SecurityScanner.scan() and threaded through so the
|
|
91
|
+
* truncation finding it emits matches what actually gets scanned. Omitted
|
|
92
|
+
* (undefined) falls back to safeRegexTest's own default.
|
|
68
93
|
*/
|
|
69
|
-
|
|
94
|
+
maxLength?: number): SecurityFinding[];
|
|
70
95
|
/**
|
|
71
96
|
* SMI-685: Calculate risk score from findings
|
|
72
97
|
* SMI-1513: Accounts for confidence levels (low confidence = reduced weight)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityScanner.helpers.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAElB,
|
|
1
|
+
{"version":3,"file":"SecurityScanner.helpers.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAElB,YAAY,EACb,MAAM,YAAY,CAAA;AAcnB;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,OAAO,CAAA;IACpB,OAAO,EAAE,OAAO,CAAA;IAChB,cAAc,EAAE,OAAO,CAAA;IACvB,YAAY,EAAE,OAAO,CAAA;IACrB;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAA;CACvB;AAMD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CA0ErE;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAW5E;AAMD,UAAU,mBAAmB;IAC3B,IAAI,EAAE,mBAAmB,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB;;;;;OAKG;IACH,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,YAAY,CAAA;CAC5C;AAUD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,mBAAmB,EAC3B,YAAY,CAAC,EAAE,WAAW,EAAE;AAC5B;;;;;;GAMG;AACH,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CAmGnB;AAMD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG;IAC/D,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,kBAAkB,CAAA;CAC9B,CA6HA"}
|