cognium-dev 4.9.24 → 4.9.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +216 -37
- package/package.json +4 -6
package/dist/cli.js
CHANGED
|
@@ -3349,8 +3349,9 @@ async function initParser(options = {}) {
|
|
|
3349
3349
|
});
|
|
3350
3350
|
}
|
|
3351
3351
|
parserInitialized = true;
|
|
3352
|
+
})().finally(() => {
|
|
3352
3353
|
parserInitializing = null;
|
|
3353
|
-
})
|
|
3354
|
+
});
|
|
3354
3355
|
return parserInitializing;
|
|
3355
3356
|
}
|
|
3356
3357
|
async function loadLanguage(language, wasmPath) {
|
|
@@ -26727,6 +26728,52 @@ function findGoRequestBodySources(sourceCode, language) {
|
|
|
26727
26728
|
continue;
|
|
26728
26729
|
}
|
|
26729
26730
|
}
|
|
26731
|
+
const wrapRe = new RegExp(`^\\s*(?:var\\s+)?([A-Za-z_]\\w*)\\s*:?=\\s*bufio\\s*\\.\\s*New(?:Scanner|Reader|ReaderSize)\\s*\\(.*${bodyRef}`);
|
|
26732
|
+
const braceDelta = (s) => {
|
|
26733
|
+
const code = s.replace(/"(?:[^"\\]|\\.)*"|`[^`]*`|'(?:[^'\\]|\\.)*'/g, '""').replace(/\/\/.*$/, "");
|
|
26734
|
+
let d = 0;
|
|
26735
|
+
for (const ch of code) {
|
|
26736
|
+
if (ch === "{")
|
|
26737
|
+
d++;
|
|
26738
|
+
else if (ch === "}")
|
|
26739
|
+
d--;
|
|
26740
|
+
}
|
|
26741
|
+
return d;
|
|
26742
|
+
};
|
|
26743
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
26744
|
+
const w = wrapRe.exec(lines[i2]);
|
|
26745
|
+
if (!w)
|
|
26746
|
+
continue;
|
|
26747
|
+
const wrapper = w[1];
|
|
26748
|
+
if (wrapper === "_")
|
|
26749
|
+
continue;
|
|
26750
|
+
const readRe = new RegExp(`(?<![\\w.])${wrapper}\\s*\\.\\s*(Text|Bytes|ReadString|ReadBytes|ReadLine|ReadSlice)\\s*\\(`);
|
|
26751
|
+
const assignRe = new RegExp(`^\\s*(?:var\\s+)?([A-Za-z_][\\w\\s,]*?)\\s*:?=(?!=)\\s*(?:string\\s*\\(\\s*)?${wrapper}\\s*\\.\\s*(?:Text|Bytes|ReadString|ReadBytes|ReadLine|ReadSlice)\\s*\\(`);
|
|
26752
|
+
const rebindRe = new RegExp(`(?<![\\w.])${wrapper}\\s*:?=(?!=)`);
|
|
26753
|
+
let depth = 0;
|
|
26754
|
+
for (let j = i2 + 1;j < lines.length; j++) {
|
|
26755
|
+
depth += braceDelta(lines[j - 1]);
|
|
26756
|
+
if (depth < 0)
|
|
26757
|
+
break;
|
|
26758
|
+
const line = lines[j];
|
|
26759
|
+
if (/^\s*\/\//.test(line))
|
|
26760
|
+
continue;
|
|
26761
|
+
if (rebindRe.test(line))
|
|
26762
|
+
break;
|
|
26763
|
+
const rd = readRe.exec(line);
|
|
26764
|
+
if (!rd)
|
|
26765
|
+
continue;
|
|
26766
|
+
const as = assignRe.exec(line);
|
|
26767
|
+
let variable = "<inline>";
|
|
26768
|
+
if (as) {
|
|
26769
|
+
const bound = as[1].split(",").map((v) => v.trim()).find((v) => v !== "_" && v !== "err" && /^[A-Za-z_]\w*$/.test(v));
|
|
26770
|
+
if (!bound)
|
|
26771
|
+
continue;
|
|
26772
|
+
variable = bound;
|
|
26773
|
+
}
|
|
26774
|
+
push(variable, j + 1, `bufio ${wrapper}.${rd[1]}() over req.Body`);
|
|
26775
|
+
}
|
|
26776
|
+
}
|
|
26730
26777
|
return sources;
|
|
26731
26778
|
}
|
|
26732
26779
|
function findCSharpRequestSources(sourceCode, language) {
|
|
@@ -26748,12 +26795,57 @@ function findCSharpRequestSources(sourceCode, language) {
|
|
|
26748
26795
|
formFileParams.add(d[1]);
|
|
26749
26796
|
}
|
|
26750
26797
|
const formFileReadRe = formFileParams.size > 0 ? new RegExp(`\\b(?:${[...formFileParams].join("|")})\\s*\\.\\s*(?:FileName|ContentType)\\b`) : null;
|
|
26798
|
+
const classify = (text) => requestReadRe.test(text) ? "http_param" : formFileReadRe?.test(text) ? "http_param" : consoleReadRe.test(text) ? "io_input" : envReadRe.test(text) ? "env_input" : null;
|
|
26799
|
+
const inlineReads = [
|
|
26800
|
+
[requestReadRe, "http_param"],
|
|
26801
|
+
[formFileReadRe, "http_param"],
|
|
26802
|
+
[consoleReadRe, "io_input"],
|
|
26803
|
+
[envReadRe, "env_input"]
|
|
26804
|
+
];
|
|
26805
|
+
const inlineRead = (text) => {
|
|
26806
|
+
const argsStart = text.indexOf("(");
|
|
26807
|
+
for (const [re, type] of inlineReads) {
|
|
26808
|
+
if (!re)
|
|
26809
|
+
continue;
|
|
26810
|
+
const g = new RegExp(re.source, "g");
|
|
26811
|
+
let hit;
|
|
26812
|
+
while ((hit = g.exec(text)) !== null) {
|
|
26813
|
+
if (hit.index > argsStart) {
|
|
26814
|
+
return { type, read: hit[0].replace(/\s+/g, "").replace(/[([]$/, "") };
|
|
26815
|
+
}
|
|
26816
|
+
}
|
|
26817
|
+
}
|
|
26818
|
+
return null;
|
|
26819
|
+
};
|
|
26820
|
+
const exprStmtCallRe = /^\s*(?:await\s+)?[A-Za-z_][\w.]*(?:<[^>]*>)?\s*\(.*\)\s*;\s*$/;
|
|
26821
|
+
const nonCallKeywordRe = /^\s*(?:await\s+)?(?:if|while|for|foreach|switch|using|lock|return|throw|catch|when|nameof|typeof|sizeof|default)\b/;
|
|
26751
26822
|
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
26752
26823
|
const m = assignRe.exec(lines[i2]);
|
|
26753
|
-
if (!m)
|
|
26824
|
+
if (!m) {
|
|
26825
|
+
const stmt = lines[i2];
|
|
26826
|
+
if (!exprStmtCallRe.test(stmt) || nonCallKeywordRe.test(stmt))
|
|
26827
|
+
continue;
|
|
26828
|
+
const hit = inlineRead(stmt);
|
|
26829
|
+
if (!hit)
|
|
26830
|
+
continue;
|
|
26831
|
+
const { type: type2, read } = hit;
|
|
26832
|
+
const lineNumber2 = i2 + 1;
|
|
26833
|
+
if (sources.some((s) => s.line === lineNumber2))
|
|
26834
|
+
continue;
|
|
26835
|
+
const code = stmt.trim();
|
|
26836
|
+
sources.push({
|
|
26837
|
+
type: type2,
|
|
26838
|
+
location: `${read} in ${code.substring(0, 50)}${code.length > 50 ? "..." : ""}`,
|
|
26839
|
+
severity: "high",
|
|
26840
|
+
line: lineNumber2,
|
|
26841
|
+
confidence: 1,
|
|
26842
|
+
variable: "<inline>",
|
|
26843
|
+
code
|
|
26844
|
+
});
|
|
26754
26845
|
continue;
|
|
26846
|
+
}
|
|
26755
26847
|
const [, varName, rhs] = m;
|
|
26756
|
-
const type =
|
|
26848
|
+
const type = classify(rhs);
|
|
26757
26849
|
if (!type)
|
|
26758
26850
|
continue;
|
|
26759
26851
|
const lineNumber = i2 + 1;
|
|
@@ -37425,6 +37517,18 @@ function maskStringLiteralsForTokenScan(expr) {
|
|
|
37425
37517
|
}
|
|
37426
37518
|
function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachableLines, tainted, code, language, types) {
|
|
37427
37519
|
const flows = [];
|
|
37520
|
+
const goFnRanges = language === "go" && types ? types.flatMap((t) => t.methods.map((m) => [m.start_line, m.end_line])) : [];
|
|
37521
|
+
const goFnStart = (line) => {
|
|
37522
|
+
let best = -1;
|
|
37523
|
+
let bestSpan = -1;
|
|
37524
|
+
for (const [start2, end] of goFnRanges) {
|
|
37525
|
+
if (line >= start2 && line <= end && end - start2 > bestSpan) {
|
|
37526
|
+
best = start2;
|
|
37527
|
+
bestSpan = end - start2;
|
|
37528
|
+
}
|
|
37529
|
+
}
|
|
37530
|
+
return best;
|
|
37531
|
+
};
|
|
37428
37532
|
const sourcesWithVar = sources.filter((s) => typeof s.variable === "string" && s.variable.length > 0);
|
|
37429
37533
|
const aliasSanitizedFor = new Map;
|
|
37430
37534
|
if (language === "python" && typeof code === "string") {
|
|
@@ -37833,6 +37937,12 @@ function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachabl
|
|
|
37833
37937
|
if (source.in_method && call.in_method && source.in_method !== call.in_method) {
|
|
37834
37938
|
continue;
|
|
37835
37939
|
}
|
|
37940
|
+
if (goFnRanges.length > 0) {
|
|
37941
|
+
const srcFn = goFnStart(source.line);
|
|
37942
|
+
const sinkFn = goFnStart(sink.line);
|
|
37943
|
+
if (srcFn !== -1 && sinkFn !== -1 && srcFn !== sinkFn)
|
|
37944
|
+
continue;
|
|
37945
|
+
}
|
|
37836
37946
|
if (complex) {
|
|
37837
37947
|
const re = reCache.get(source.variable);
|
|
37838
37948
|
if (!re || !re.test(expr))
|
|
@@ -49945,18 +50055,24 @@ async function enumerate(dir, out2) {
|
|
|
49945
50055
|
}
|
|
49946
50056
|
}
|
|
49947
50057
|
}
|
|
49948
|
-
function
|
|
49949
|
-
|
|
49950
|
-
let bestLen = -1;
|
|
50058
|
+
function createOwnerIndex(modules) {
|
|
50059
|
+
const byRoot = new Map;
|
|
49951
50060
|
for (const m of modules) {
|
|
49952
|
-
if (
|
|
49953
|
-
|
|
49954
|
-
|
|
49955
|
-
|
|
49956
|
-
|
|
50061
|
+
if (!byRoot.has(m.root))
|
|
50062
|
+
byRoot.set(m.root, m);
|
|
50063
|
+
}
|
|
50064
|
+
return (file) => {
|
|
50065
|
+
let p = file;
|
|
50066
|
+
for (;; ) {
|
|
50067
|
+
const hit = byRoot.get(p);
|
|
50068
|
+
if (hit)
|
|
50069
|
+
return hit;
|
|
50070
|
+
const slash = p.lastIndexOf("/");
|
|
50071
|
+
if (slash <= 0)
|
|
50072
|
+
return;
|
|
50073
|
+
p = p.slice(0, slash);
|
|
49957
50074
|
}
|
|
49958
|
-
}
|
|
49959
|
-
return best;
|
|
50075
|
+
};
|
|
49960
50076
|
}
|
|
49961
50077
|
|
|
49962
50078
|
// ../project-profile-detect/dist/publication-detect.js
|
|
@@ -50115,6 +50231,7 @@ async function detectProjectProfiles(scanRoot, options = {}) {
|
|
|
50115
50231
|
}
|
|
50116
50232
|
const profileByFile = new Map;
|
|
50117
50233
|
const unknownFiles = [];
|
|
50234
|
+
const ownerIndex = createOwnerIndex(modules);
|
|
50118
50235
|
for (const file of files) {
|
|
50119
50236
|
const rel = relative3(scanRoot, file);
|
|
50120
50237
|
const ov = applyOverrides(rel, compiledOverrides);
|
|
@@ -50128,7 +50245,7 @@ async function detectProjectProfiles(scanRoot, options = {}) {
|
|
|
50128
50245
|
profileByFile.set(file, `${shape2}/${env2}`);
|
|
50129
50246
|
continue;
|
|
50130
50247
|
}
|
|
50131
|
-
const owner =
|
|
50248
|
+
const owner = ownerIndex(file);
|
|
50132
50249
|
if (!owner) {
|
|
50133
50250
|
profileByFile.set(file, "unknown");
|
|
50134
50251
|
unknownFiles.push(file);
|
|
@@ -50156,19 +50273,30 @@ var YELLOW = "\x1B[93m";
|
|
|
50156
50273
|
var BLUE = "\x1B[94m";
|
|
50157
50274
|
var CYAN = "\x1B[96m";
|
|
50158
50275
|
var MAGENTA = "\x1B[95m";
|
|
50276
|
+
function colorEnabled() {
|
|
50277
|
+
const noColor = process.env.NO_COLOR;
|
|
50278
|
+
if (noColor !== undefined && noColor !== "")
|
|
50279
|
+
return false;
|
|
50280
|
+
if (process.env.TERM === "dumb")
|
|
50281
|
+
return false;
|
|
50282
|
+
return true;
|
|
50283
|
+
}
|
|
50284
|
+
function paint(code, text) {
|
|
50285
|
+
return colorEnabled() ? `${code}${text}${RESET}` : text;
|
|
50286
|
+
}
|
|
50159
50287
|
var colors = {
|
|
50160
|
-
red: (text) =>
|
|
50161
|
-
green: (text) =>
|
|
50162
|
-
yellow: (text) =>
|
|
50163
|
-
blue: (text) =>
|
|
50164
|
-
cyan: (text) =>
|
|
50165
|
-
magenta: (text) =>
|
|
50166
|
-
bold: (text) =>
|
|
50288
|
+
red: (text) => paint(RED, text),
|
|
50289
|
+
green: (text) => paint(GREEN, text),
|
|
50290
|
+
yellow: (text) => paint(YELLOW, text),
|
|
50291
|
+
blue: (text) => paint(BLUE, text),
|
|
50292
|
+
cyan: (text) => paint(CYAN, text),
|
|
50293
|
+
magenta: (text) => paint(MAGENTA, text),
|
|
50294
|
+
bold: (text) => paint(BOLD, text),
|
|
50167
50295
|
dim: (text) => text
|
|
50168
50296
|
};
|
|
50169
50297
|
|
|
50170
50298
|
// src/version.ts
|
|
50171
|
-
var version = "4.9.
|
|
50299
|
+
var version = "4.9.26";
|
|
50172
50300
|
|
|
50173
50301
|
// src/formatters.ts
|
|
50174
50302
|
var LIBRARY_API_SURFACE_TAG2 = "library-api-surface:caller-responsibility";
|
|
@@ -50713,8 +50841,8 @@ function generateSarifResults(results, crossFileData) {
|
|
|
50713
50841
|
|
|
50714
50842
|
// src/build-info.ts
|
|
50715
50843
|
var buildInfo = {
|
|
50716
|
-
gitSha: "
|
|
50717
|
-
builtAt: "2026-09-
|
|
50844
|
+
gitSha: "178c681",
|
|
50845
|
+
builtAt: "2026-09-24T18:11:45.249Z"
|
|
50718
50846
|
};
|
|
50719
50847
|
|
|
50720
50848
|
// src/utils/args.ts
|
|
@@ -50773,7 +50901,7 @@ COMMANDS:
|
|
|
50773
50901
|
version Display version information
|
|
50774
50902
|
|
|
50775
50903
|
SCAN OPTIONS:
|
|
50776
|
-
-l, --language <lang> Scan only files for language (bash|go|html|java|javascript|typescript|python|rust)
|
|
50904
|
+
-l, --language <lang> Scan only files for language (bash|csharp|go|html|java|javascript|typescript|python|rust)
|
|
50777
50905
|
-f, --format <format> Output format (text|json|sarif) [default: text]
|
|
50778
50906
|
--threads <n> Parallel analysis threads [default: 4]
|
|
50779
50907
|
--severity <level> Filter by severity:
|
|
@@ -50806,7 +50934,7 @@ SCAN OPTIONS:
|
|
|
50806
50934
|
surfaced in output (text warning / JSON / SARIF field).
|
|
50807
50935
|
|
|
50808
50936
|
METRICS OPTIONS:
|
|
50809
|
-
-l, --language <lang> Analyze only files for language (bash|go|html|java|javascript|typescript|python|rust)
|
|
50937
|
+
-l, --language <lang> Analyze only files for language (bash|csharp|go|html|java|javascript|typescript|python|rust)
|
|
50810
50938
|
-f, --format <format> Output format (text|json) [default: text]
|
|
50811
50939
|
--category <cats> Filter by metric category (comma-separated):
|
|
50812
50940
|
- Valid categories: complexity, size, coupling,
|
|
@@ -50915,19 +51043,19 @@ class Spinner {
|
|
|
50915
51043
|
succeed(text) {
|
|
50916
51044
|
this.stop();
|
|
50917
51045
|
const message = text || this._text;
|
|
50918
|
-
console.error(
|
|
51046
|
+
console.error(`${colors.green(CHECKMARK)} ${message}`);
|
|
50919
51047
|
return this;
|
|
50920
51048
|
}
|
|
50921
51049
|
fail(text) {
|
|
50922
51050
|
this.stop();
|
|
50923
51051
|
const message = text || this._text;
|
|
50924
|
-
console.error(
|
|
51052
|
+
console.error(`${colors.red(CROSS)} ${message}`);
|
|
50925
51053
|
return this;
|
|
50926
51054
|
}
|
|
50927
51055
|
warn(text) {
|
|
50928
51056
|
this.stop();
|
|
50929
51057
|
const message = text || this._text;
|
|
50930
|
-
console.error(
|
|
51058
|
+
console.error(`${colors.yellow(WARNING)} ${message}`);
|
|
50931
51059
|
return this;
|
|
50932
51060
|
}
|
|
50933
51061
|
set text(value) {
|
|
@@ -50954,8 +51082,7 @@ function loadConfig(profilePath) {
|
|
|
50954
51082
|
const content = readFileSync(configPath, "utf-8");
|
|
50955
51083
|
return JSON.parse(content);
|
|
50956
51084
|
} catch (err2) {
|
|
50957
|
-
|
|
50958
|
-
return null;
|
|
51085
|
+
throw new Error(`Failed to parse ${configPath}: ${err2 instanceof Error ? err2.message : String(err2)}. ` + "Fix the JSON or remove the file.");
|
|
50959
51086
|
}
|
|
50960
51087
|
}
|
|
50961
51088
|
function convertConfigToPassOptions(config) {
|
|
@@ -51021,6 +51148,27 @@ function applySuppressionsToResults(results, suppressions, basePath) {
|
|
|
51021
51148
|
return { ...result, vulnerabilities: filteredVulns };
|
|
51022
51149
|
});
|
|
51023
51150
|
}
|
|
51151
|
+
function applySuppressionsToTaintPaths(paths, suppressions, basePath) {
|
|
51152
|
+
if (suppressions.length === 0)
|
|
51153
|
+
return paths;
|
|
51154
|
+
return paths.filter((path) => {
|
|
51155
|
+
for (const supp of suppressions) {
|
|
51156
|
+
const sinkType = path.sink.type;
|
|
51157
|
+
if (supp.pass !== sinkType && supp.pass !== `cross-file-${sinkType}`)
|
|
51158
|
+
continue;
|
|
51159
|
+
if (supp.file) {
|
|
51160
|
+
const suppFile = supp.file.replace(/^\.\//, "");
|
|
51161
|
+
const relativeFile = relative4(basePath, path.sink.file) || path.sink.file;
|
|
51162
|
+
if (suppFile !== relativeFile && suppFile !== path.sink.file)
|
|
51163
|
+
continue;
|
|
51164
|
+
}
|
|
51165
|
+
if (supp.line !== undefined && supp.line !== path.sink.line)
|
|
51166
|
+
continue;
|
|
51167
|
+
return false;
|
|
51168
|
+
}
|
|
51169
|
+
return true;
|
|
51170
|
+
});
|
|
51171
|
+
}
|
|
51024
51172
|
var TEST_PATTERNS = [
|
|
51025
51173
|
/[\/\\]test[\/\\]/i,
|
|
51026
51174
|
/[\/\\]tests[\/\\]/i,
|
|
@@ -51078,9 +51226,30 @@ function detectLanguage7(filePath) {
|
|
|
51078
51226
|
const ext = extname(filePath).toLowerCase();
|
|
51079
51227
|
return LANG_MAP[ext] || null;
|
|
51080
51228
|
}
|
|
51229
|
+
var SUPPORTED_SCAN_LANGUAGES = [
|
|
51230
|
+
...new Set(Object.values(LANG_MAP))
|
|
51231
|
+
].sort();
|
|
51081
51232
|
function normalizeLanguage(language) {
|
|
51082
51233
|
return language.trim().toLowerCase();
|
|
51083
51234
|
}
|
|
51235
|
+
function resolveScanLanguage(raw) {
|
|
51236
|
+
if (raw === undefined || raw === "")
|
|
51237
|
+
return;
|
|
51238
|
+
const normalized = normalizeLanguage(String(raw));
|
|
51239
|
+
if (!SUPPORTED_SCAN_LANGUAGES.includes(normalized)) {
|
|
51240
|
+
throw new Error(`Invalid language: ${normalized}
|
|
51241
|
+
Valid options: ${SUPPORTED_SCAN_LANGUAGES.join(", ")}`);
|
|
51242
|
+
}
|
|
51243
|
+
return normalized;
|
|
51244
|
+
}
|
|
51245
|
+
function languageFromCliOptions(options) {
|
|
51246
|
+
try {
|
|
51247
|
+
return resolveScanLanguage(options.language || options.l);
|
|
51248
|
+
} catch (err2) {
|
|
51249
|
+
console.error(colors.red(`Error: ${err2.message}`));
|
|
51250
|
+
process.exit(1);
|
|
51251
|
+
}
|
|
51252
|
+
}
|
|
51084
51253
|
function fileMatchesLanguage(filePath, language) {
|
|
51085
51254
|
const detected = detectLanguage7(filePath);
|
|
51086
51255
|
if (!detected)
|
|
@@ -51091,9 +51260,13 @@ function fileMatchesLanguage(filePath, language) {
|
|
|
51091
51260
|
}
|
|
51092
51261
|
function matchesGlob(filePath, pattern) {
|
|
51093
51262
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
51094
|
-
|
|
51263
|
+
let normalizedPattern = pattern.replace(/\\/g, "/");
|
|
51264
|
+
normalizedPattern = normalizedPattern.replace(/\*{3,}/g, "**").replace(/(?:\*\*\/)+/g, "**/").replace(/(?:\/\*\*)+/g, "/**");
|
|
51265
|
+
const globstarCount = (normalizedPattern.match(/\*\*/g) ?? []).length;
|
|
51266
|
+
if (globstarCount > 4)
|
|
51267
|
+
return false;
|
|
51095
51268
|
let regex = normalizedPattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\?/g, ".");
|
|
51096
|
-
regex = regex.replace(/\{\{GLOBSTAR\}\}\//g, "(
|
|
51269
|
+
regex = regex.replace(/\{\{GLOBSTAR\}\}\//g, "(?:[^/]+/)*").replace(/\/\{\{GLOBSTAR\}\}/g, "(?:/[^/]+)*").replace(/\{\{GLOBSTAR\}\}/g, "[^]*");
|
|
51097
51270
|
return new RegExp("^" + regex + "$").test(normalizedPath);
|
|
51098
51271
|
}
|
|
51099
51272
|
function matchesAnyPattern(filePath, patterns) {
|
|
@@ -51484,9 +51657,12 @@ async function runScan(targetPath, options) {
|
|
|
51484
51657
|
if (spin)
|
|
51485
51658
|
spin.succeed(`Scanned ${files.length} file(s)`);
|
|
51486
51659
|
if (suppressions.length > 0) {
|
|
51487
|
-
const beforeCount = results.reduce((sum, r) => sum + r.vulnerabilities.length, 0);
|
|
51660
|
+
const beforeCount = results.reduce((sum, r) => sum + r.vulnerabilities.length, 0) + (crossFileData?.taintPaths.length ?? 0);
|
|
51488
51661
|
results = applySuppressionsToResults(results, suppressions, process.cwd());
|
|
51489
|
-
|
|
51662
|
+
if (crossFileData) {
|
|
51663
|
+
crossFileData.taintPaths = applySuppressionsToTaintPaths(crossFileData.taintPaths, suppressions, process.cwd());
|
|
51664
|
+
}
|
|
51665
|
+
const afterCount = results.reduce((sum, r) => sum + r.vulnerabilities.length, 0) + (crossFileData?.taintPaths.length ?? 0);
|
|
51490
51666
|
if (!options.quiet && beforeCount !== afterCount) {
|
|
51491
51667
|
console.error(colors.dim(`Suppressed ${beforeCount - afterCount} finding(s) via config`));
|
|
51492
51668
|
}
|
|
@@ -52035,7 +52211,7 @@ Usage: cognium-dev metrics <path> [options]`);
|
|
|
52035
52211
|
category: options.category,
|
|
52036
52212
|
output: options.output || options.o,
|
|
52037
52213
|
quiet: options.quiet === true || options.q === true,
|
|
52038
|
-
language:
|
|
52214
|
+
language: languageFromCliOptions(options),
|
|
52039
52215
|
excludeTests: options["exclude-tests"] === true,
|
|
52040
52216
|
profile: options.profile || options.p
|
|
52041
52217
|
};
|
|
@@ -52073,7 +52249,7 @@ Usage: cognium-dev scan <path> [options]`);
|
|
|
52073
52249
|
}
|
|
52074
52250
|
const targetPath = args2[0];
|
|
52075
52251
|
const scanOptions = {
|
|
52076
|
-
language:
|
|
52252
|
+
language: languageFromCliOptions(options),
|
|
52077
52253
|
format: options.format || options.f || "text",
|
|
52078
52254
|
threads: parseInt(options.threads || "4", 10),
|
|
52079
52255
|
severity: options.severity,
|
|
@@ -52107,12 +52283,15 @@ main().catch((error) => {
|
|
|
52107
52283
|
process.exit(2);
|
|
52108
52284
|
});
|
|
52109
52285
|
export {
|
|
52286
|
+
resolveScanLanguage,
|
|
52110
52287
|
matchesGlob,
|
|
52111
52288
|
loadConfig,
|
|
52112
52289
|
isTestFile2 as isTestFile,
|
|
52113
52290
|
detectLanguage7 as detectLanguage,
|
|
52114
52291
|
dedupeVulnerabilities,
|
|
52115
52292
|
convertConfigToPassOptions,
|
|
52293
|
+
applySuppressionsToTaintPaths,
|
|
52116
52294
|
applySuppressionsToResults,
|
|
52295
|
+
SUPPORTED_SCAN_LANGUAGES,
|
|
52117
52296
|
PASS_REGISTRY
|
|
52118
52297
|
};
|
package/package.json
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.26",
|
|
4
4
|
"description": "Static Application Security Testing CLI for detecting security vulnerabilities via taint tracking",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
5
|
"bin": {
|
|
8
6
|
"cognium-dev": "dist/cli.js"
|
|
9
7
|
},
|
|
@@ -14,7 +12,7 @@
|
|
|
14
12
|
"test": "bun test",
|
|
15
13
|
"clean": "rm -rf dist cognium-dev cognium-dev-* *.bun-build wasm",
|
|
16
14
|
"typecheck": "tsc --noEmit",
|
|
17
|
-
"version": "node -e \"const v = require('./package.json').version; require('fs').writeFileSync('src/version.ts', '/**\\n * Version information\\n *\\n * Kept in sync with package.json via the \\`version\\` npm lifecycle script.\\n * Do not edit manually
|
|
15
|
+
"version": "node -e \"const v = require('./package.json').version; require('fs').writeFileSync('src/version.ts', '/**\\n * Version information\\n *\\n * Kept in sync with package.json via the \\`version\\` npm lifecycle script.\\n * Do not edit manually \u2014 use \\`npm version patch|minor|major\\` instead.\\n */\\nexport const version = \\x27' + v + '\\x27;\\n')\" && git add src/version.ts",
|
|
18
16
|
"dogfood": "bun run src/cli.ts scan src/ -q",
|
|
19
17
|
"prepublishOnly": "bun run build",
|
|
20
18
|
"test:coverage": "bun test --coverage"
|
|
@@ -66,8 +64,8 @@
|
|
|
66
64
|
"registry": "https://registry.npmjs.org/"
|
|
67
65
|
},
|
|
68
66
|
"dependencies": {
|
|
69
|
-
"@cognium/project-profile-detect": "1.1.
|
|
70
|
-
"circle-ir": "4.9.
|
|
67
|
+
"@cognium/project-profile-detect": "1.1.2",
|
|
68
|
+
"circle-ir": "4.9.26"
|
|
71
69
|
},
|
|
72
70
|
"devDependencies": {
|
|
73
71
|
"@types/node": "^26.6.1",
|