cognium-dev 3.102.0 → 3.104.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +99 -2
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -23544,6 +23544,7 @@ var PROTOCOL_CLIENT_PACKAGES = [
|
|
|
23544
23544
|
];
|
|
23545
23545
|
var OS_EXEC_RECEIVER_RE = /\b(?:Runtime|ProcessBuilder|DefaultExecutor|Executor|Exec|Launcher|ProcStarter|ProcessExecutor|RuntimeUtil)\s*[.(]/;
|
|
23546
23546
|
var PROCESS_BUILDER_ARGV_FORM_RE = /\bnew\s+ProcessBuilder\s*\(\s*(?:Arrays\.asList\b|List\.of\b|Collections\.singletonList\b|new\s+ArrayList\b|new\s+String\s*\[\s*\]\s*\{|"[^"]*"\s*,)/;
|
|
23547
|
+
var JAVA_THROW_STATEMENT_RE = /^\s*throw\s+new\s+\w+(?:Exception|Error)\b/;
|
|
23547
23548
|
function resolveJavaReceiverType(receiver, sinkLine, sourceLines) {
|
|
23548
23549
|
if (!receiver || !/^[A-Za-z_]\w*$/.test(receiver))
|
|
23549
23550
|
return null;
|
|
@@ -23831,6 +23832,16 @@ class SinkFilterPass {
|
|
|
23831
23832
|
return true;
|
|
23832
23833
|
});
|
|
23833
23834
|
}
|
|
23835
|
+
if (language === "java") {
|
|
23836
|
+
const sourceLines = ctx.code.split(`
|
|
23837
|
+
`);
|
|
23838
|
+
filtered = filtered.filter((sink) => {
|
|
23839
|
+
const sinkLineText = sourceLines[sink.line - 1] ?? "";
|
|
23840
|
+
if (JAVA_THROW_STATEMENT_RE.test(sinkLineText))
|
|
23841
|
+
return false;
|
|
23842
|
+
return true;
|
|
23843
|
+
});
|
|
23844
|
+
}
|
|
23834
23845
|
return { sources, sinks: filtered, sanitizers };
|
|
23835
23846
|
}
|
|
23836
23847
|
}
|
|
@@ -26463,6 +26474,10 @@ class NullDerefPass {
|
|
|
26463
26474
|
}
|
|
26464
26475
|
|
|
26465
26476
|
// ../circle-ir/dist/analysis/passes/resource-leak-pass.js
|
|
26477
|
+
function escapeRegex(s) {
|
|
26478
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
26479
|
+
}
|
|
26480
|
+
var FACTORY_METHOD_NAME_RE = /^(?:open|create|new|get|make|build)[A-Z]/;
|
|
26466
26481
|
var RESOURCE_CTORS = new Set([
|
|
26467
26482
|
"FileInputStream",
|
|
26468
26483
|
"FileOutputStream",
|
|
@@ -26537,7 +26552,18 @@ class ResourceLeakPass {
|
|
|
26537
26552
|
const methodInfo = graph.methodAtLine(openLine);
|
|
26538
26553
|
if (!methodInfo)
|
|
26539
26554
|
continue;
|
|
26555
|
+
const methodStart = methodInfo.method.start_line;
|
|
26540
26556
|
const methodEnd = methodInfo.method.end_line;
|
|
26557
|
+
if (this.isReturnedToCaller(codeLines, resourceVar, methodStart, methodEnd)) {
|
|
26558
|
+
continue;
|
|
26559
|
+
}
|
|
26560
|
+
const fieldName = this.fieldStoredName(codeLines, resourceVar, openLine, methodEnd);
|
|
26561
|
+
if (fieldName && this.classHasCloseMethodFor(graph, fieldName, methodInfo.type)) {
|
|
26562
|
+
continue;
|
|
26563
|
+
}
|
|
26564
|
+
if (this.isFactoryMethod(methodInfo.method)) {
|
|
26565
|
+
continue;
|
|
26566
|
+
}
|
|
26541
26567
|
const closeCall = graph.ir.calls.find((c) => CLOSE_METHODS.has(c.method_name) && c.receiver === resourceVar && c.location.line > openLine && c.location.line <= methodEnd);
|
|
26542
26568
|
const snippet = (codeLines[openLine - 1] ?? "").trim();
|
|
26543
26569
|
if (!closeCall) {
|
|
@@ -26601,6 +26627,39 @@ class ResourceLeakPass {
|
|
|
26601
26627
|
}
|
|
26602
26628
|
return false;
|
|
26603
26629
|
}
|
|
26630
|
+
isReturnedToCaller(lines, variable, fromLine, toLine) {
|
|
26631
|
+
const varRe = new RegExp(`\\breturn\\b[^;]*\\b${escapeRegex(variable)}\\b`);
|
|
26632
|
+
for (let l = fromLine;l <= toLine && l <= lines.length; l++) {
|
|
26633
|
+
if (varRe.test(lines[l - 1] ?? ""))
|
|
26634
|
+
return true;
|
|
26635
|
+
}
|
|
26636
|
+
return false;
|
|
26637
|
+
}
|
|
26638
|
+
fieldStoredName(lines, variable, openLine, toLine) {
|
|
26639
|
+
const thisAssignRe = new RegExp(`\\bthis\\s*\\.\\s*(\\w+)\\s*=\\s*${escapeRegex(variable)}\\b`);
|
|
26640
|
+
for (let l = openLine;l <= toLine && l <= lines.length; l++) {
|
|
26641
|
+
const m = thisAssignRe.exec(lines[l - 1] ?? "");
|
|
26642
|
+
if (m)
|
|
26643
|
+
return m[1];
|
|
26644
|
+
}
|
|
26645
|
+
return null;
|
|
26646
|
+
}
|
|
26647
|
+
classHasCloseMethodFor(graph, fieldName, type) {
|
|
26648
|
+
for (const c of graph.ir.calls) {
|
|
26649
|
+
if (c.location.line < type.start_line || c.location.line > type.end_line)
|
|
26650
|
+
continue;
|
|
26651
|
+
if (c.receiver !== fieldName)
|
|
26652
|
+
continue;
|
|
26653
|
+
if (CLOSE_METHODS.has(c.method_name))
|
|
26654
|
+
return true;
|
|
26655
|
+
}
|
|
26656
|
+
return false;
|
|
26657
|
+
}
|
|
26658
|
+
isFactoryMethod(method) {
|
|
26659
|
+
if (!method.return_type || method.return_type === "void")
|
|
26660
|
+
return false;
|
|
26661
|
+
return FACTORY_METHOD_NAME_RE.test(method.name);
|
|
26662
|
+
}
|
|
26604
26663
|
}
|
|
26605
26664
|
|
|
26606
26665
|
// ../circle-ir/dist/graph/scope-graph.js
|
|
@@ -29844,6 +29903,33 @@ function mapReturnValueToCorsRule(returnValue) {
|
|
|
29844
29903
|
};
|
|
29845
29904
|
}
|
|
29846
29905
|
|
|
29906
|
+
// ../circle-ir/dist/analysis/passes/_fp-allowlists.js
|
|
29907
|
+
var PEM_BODY_RE = /[A-Za-z0-9+/]{30,}/;
|
|
29908
|
+
function pemHasInlineBody(lines, hitLineIdx) {
|
|
29909
|
+
const end = Math.min(hitLineIdx + 5, lines.length);
|
|
29910
|
+
for (let l = hitLineIdx;l < end; l++) {
|
|
29911
|
+
if (PEM_BODY_RE.test(lines[l] ?? ""))
|
|
29912
|
+
return true;
|
|
29913
|
+
}
|
|
29914
|
+
return false;
|
|
29915
|
+
}
|
|
29916
|
+
var CLI_OPTION_KEY_RE = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)+$/;
|
|
29917
|
+
function isCliOptionKeyValue(value) {
|
|
29918
|
+
return value.length <= 48 && CLI_OPTION_KEY_RE.test(value);
|
|
29919
|
+
}
|
|
29920
|
+
var PROTOCOL_MANDATED_PATH_RE = /(?:^|[\\/])(?:ntlm|kerberos|krb5|smb1?|sasl[\\/]cram-md5?|digest)(?:[\\/]|$)/i;
|
|
29921
|
+
var PROTOCOL_MANDATED_CLASS_RE = /\b(?:N[Tt][Ll][Mm](?:Scheme|Engine|AuthHandler|AuthScheme)|Krb5\w+|KerberosClient|Smb\w*Signing|CramMd5\w*|DigestScheme)\b/;
|
|
29922
|
+
var PROTOCOL_MANDATED_CITATION_RE = /\b(?:MS-NLMP|RFC\s*4757|RFC\s*3961|RFC\s*2617|RFC\s*2195|CRAM-MD5)\b/i;
|
|
29923
|
+
function isProtocolMandatedCryptoFile(file, code) {
|
|
29924
|
+
if (PROTOCOL_MANDATED_PATH_RE.test(file))
|
|
29925
|
+
return true;
|
|
29926
|
+
if (PROTOCOL_MANDATED_CLASS_RE.test(code))
|
|
29927
|
+
return true;
|
|
29928
|
+
if (PROTOCOL_MANDATED_CITATION_RE.test(code))
|
|
29929
|
+
return true;
|
|
29930
|
+
return false;
|
|
29931
|
+
}
|
|
29932
|
+
|
|
29847
29933
|
// ../circle-ir/dist/analysis/passes/scan-secrets-pass.js
|
|
29848
29934
|
var TEST_PATH_RE3 = /(?:^|[\\/])(?:test|tests|spec|specs|__tests?__|__mocks?__|fixtures?|testdata)(?:[\\/]|$)/i;
|
|
29849
29935
|
var TEST_FILENAME_RE = /(?:\.(?:test|spec)\.[cm]?[jt]sx?|_test\.go|_test\.py|Test\.java|Tests\.java)$/i;
|
|
@@ -30010,6 +30096,8 @@ function isLikelyCredentialAssignment(line) {
|
|
|
30010
30096
|
return null;
|
|
30011
30097
|
if (/^[0-9]+$/.test(value) && value.length < 16)
|
|
30012
30098
|
return null;
|
|
30099
|
+
if (isCliOptionKeyValue(value))
|
|
30100
|
+
return null;
|
|
30013
30101
|
return { name: name2, value };
|
|
30014
30102
|
}
|
|
30015
30103
|
var STRING_LITERAL_RE = /(["'`])((?:\\.|(?!\1).){8,200})\1/g;
|
|
@@ -30216,6 +30304,9 @@ class ScanSecretsPass {
|
|
|
30216
30304
|
const m = pattern.regex.exec(lineText);
|
|
30217
30305
|
if (!m)
|
|
30218
30306
|
continue;
|
|
30307
|
+
if (pattern.name === "PEM private key" && !pemHasInlineBody(lines, i2)) {
|
|
30308
|
+
continue;
|
|
30309
|
+
}
|
|
30219
30310
|
const key = `${lineNum}:hardcoded-credential`;
|
|
30220
30311
|
if (seen.has(key))
|
|
30221
30312
|
continue;
|
|
@@ -31090,6 +31181,9 @@ class WeakCryptoPass {
|
|
|
31090
31181
|
run(ctx) {
|
|
31091
31182
|
const { graph, language, code } = ctx;
|
|
31092
31183
|
const file = graph.ir.meta.file;
|
|
31184
|
+
if (isProtocolMandatedCryptoFile(file, code)) {
|
|
31185
|
+
return { findings: [] };
|
|
31186
|
+
}
|
|
31093
31187
|
const findings = [];
|
|
31094
31188
|
const constProp = ctx.hasResult("constant-propagation") ? ctx.getResult("constant-propagation") : null;
|
|
31095
31189
|
const literalBindings = scanLiteralBindings(code, language);
|
|
@@ -31620,8 +31714,11 @@ class WeakPasswordHashPass {
|
|
|
31620
31714
|
name = "weak-password-hash";
|
|
31621
31715
|
category = "security";
|
|
31622
31716
|
run(ctx) {
|
|
31623
|
-
const { graph, language } = ctx;
|
|
31717
|
+
const { graph, language, code } = ctx;
|
|
31624
31718
|
const file = graph.ir.meta.file;
|
|
31719
|
+
if (isProtocolMandatedCryptoFile(file, code)) {
|
|
31720
|
+
return { findings: [] };
|
|
31721
|
+
}
|
|
31625
31722
|
const findings = [];
|
|
31626
31723
|
for (const call of graph.ir.calls) {
|
|
31627
31724
|
const detection = this.detect(call, language);
|
|
@@ -34956,7 +35053,7 @@ var colors = {
|
|
|
34956
35053
|
};
|
|
34957
35054
|
|
|
34958
35055
|
// src/version.ts
|
|
34959
|
-
var version = "3.
|
|
35056
|
+
var version = "3.104.0";
|
|
34960
35057
|
|
|
34961
35058
|
// src/formatters.ts
|
|
34962
35059
|
var SINK_SEVERITY = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.104.0",
|
|
4
4
|
"description": "Static Application Security Testing CLI for detecting security vulnerabilities via taint tracking",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"registry": "https://registry.npmjs.org/"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"circle-ir": "^3.
|
|
68
|
+
"circle-ir": "^3.104.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.5.0",
|