cognium-dev 3.100.0 → 3.102.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 +82 -2
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -23523,6 +23523,27 @@ var REFLECTION_LITERAL_METHODS = new Set([
|
|
|
23523
23523
|
"invoke"
|
|
23524
23524
|
]);
|
|
23525
23525
|
var JAVA_DECL_RE_TEMPLATE = "(?:\\b(?:final|public|private|protected|static)\\s+)*" + "([A-Z]\\w*(?:\\.[A-Z]\\w*)?(?:<[^>]*>)?)\\s+RECV\\b\\s*[=;,)]";
|
|
23526
|
+
var PROTOCOL_WIRE_METHODS = new Set([
|
|
23527
|
+
"executeCommand",
|
|
23528
|
+
"execute",
|
|
23529
|
+
"dispatch",
|
|
23530
|
+
"send",
|
|
23531
|
+
"publish",
|
|
23532
|
+
"command",
|
|
23533
|
+
"run"
|
|
23534
|
+
]);
|
|
23535
|
+
var PROTOCOL_CLIENT_PACKAGES = [
|
|
23536
|
+
"redis.clients.jedis",
|
|
23537
|
+
"io.lettuce",
|
|
23538
|
+
"org.springframework.data.redis",
|
|
23539
|
+
"org.springframework.data.mongodb",
|
|
23540
|
+
"org.springframework.amqp",
|
|
23541
|
+
"com.rabbitmq",
|
|
23542
|
+
"org.apache.kafka",
|
|
23543
|
+
"org.eclipse.paho"
|
|
23544
|
+
];
|
|
23545
|
+
var OS_EXEC_RECEIVER_RE = /\b(?:Runtime|ProcessBuilder|DefaultExecutor|Executor|Exec|Launcher|ProcStarter|ProcessExecutor|RuntimeUtil)\s*[.(]/;
|
|
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*,)/;
|
|
23526
23547
|
function resolveJavaReceiverType(receiver, sinkLine, sourceLines) {
|
|
23527
23548
|
if (!receiver || !/^[A-Za-z_]\w*$/.test(receiver))
|
|
23528
23549
|
return null;
|
|
@@ -23559,6 +23580,17 @@ function extractJavaCallArgs(method, line) {
|
|
|
23559
23580
|
return [];
|
|
23560
23581
|
return argsText.split(",").map((s) => s.trim());
|
|
23561
23582
|
}
|
|
23583
|
+
function hasJavaImportFromPackage(packagePrefix, sourceLines) {
|
|
23584
|
+
if (!/^[A-Za-z_][\w.]*$/.test(packagePrefix))
|
|
23585
|
+
return false;
|
|
23586
|
+
const limit = Math.min(sourceLines.length, 80);
|
|
23587
|
+
const re = new RegExp(`^\\s*import\\s+(?:static\\s+)?${packagePrefix.replace(/\./g, "\\.")}\\b`);
|
|
23588
|
+
for (let i2 = 0;i2 < limit; i2++) {
|
|
23589
|
+
if (re.test(sourceLines[i2] ?? ""))
|
|
23590
|
+
return true;
|
|
23591
|
+
}
|
|
23592
|
+
return false;
|
|
23593
|
+
}
|
|
23562
23594
|
|
|
23563
23595
|
class SinkFilterPass {
|
|
23564
23596
|
name = "sink-filter";
|
|
@@ -23761,6 +23793,44 @@ class SinkFilterPass {
|
|
|
23761
23793
|
return true;
|
|
23762
23794
|
});
|
|
23763
23795
|
}
|
|
23796
|
+
if (language === "java") {
|
|
23797
|
+
const sourceLines = ctx.code.split(`
|
|
23798
|
+
`);
|
|
23799
|
+
filtered = filtered.filter((sink) => {
|
|
23800
|
+
if (sink.type !== "command_injection")
|
|
23801
|
+
return true;
|
|
23802
|
+
const sinkLineText = sourceLines[sink.line - 1] ?? "";
|
|
23803
|
+
if (sink.method === "CommandLine" && /\bnew\s+CommandLine\s*\(/.test(sinkLineText) && hasJavaImportFromPackage("picocli", sourceLines)) {
|
|
23804
|
+
return false;
|
|
23805
|
+
}
|
|
23806
|
+
if (sink.method && PROTOCOL_WIRE_METHODS.has(sink.method)) {
|
|
23807
|
+
for (const pkg of PROTOCOL_CLIENT_PACKAGES) {
|
|
23808
|
+
if (hasJavaImportFromPackage(pkg, sourceLines)) {
|
|
23809
|
+
if (!OS_EXEC_RECEIVER_RE.test(sinkLineText)) {
|
|
23810
|
+
return false;
|
|
23811
|
+
}
|
|
23812
|
+
}
|
|
23813
|
+
}
|
|
23814
|
+
}
|
|
23815
|
+
return true;
|
|
23816
|
+
});
|
|
23817
|
+
}
|
|
23818
|
+
if (language === "java") {
|
|
23819
|
+
const sourceLines = ctx.code.split(`
|
|
23820
|
+
`);
|
|
23821
|
+
filtered = filtered.filter((sink) => {
|
|
23822
|
+
if (sink.type !== "command_injection")
|
|
23823
|
+
return true;
|
|
23824
|
+
if (sink.method !== "ProcessBuilder")
|
|
23825
|
+
return true;
|
|
23826
|
+
const sinkLineText = sourceLines[sink.line - 1] ?? "";
|
|
23827
|
+
if (!/\bnew\s+ProcessBuilder\s*\(/.test(sinkLineText))
|
|
23828
|
+
return true;
|
|
23829
|
+
if (PROCESS_BUILDER_ARGV_FORM_RE.test(sinkLineText))
|
|
23830
|
+
return false;
|
|
23831
|
+
return true;
|
|
23832
|
+
});
|
|
23833
|
+
}
|
|
23764
23834
|
return { sources, sinks: filtered, sanitizers };
|
|
23765
23835
|
}
|
|
23766
23836
|
}
|
|
@@ -33310,7 +33380,11 @@ var JAVA_FACTORIES = new Set([
|
|
|
33310
33380
|
"SchemaFactory",
|
|
33311
33381
|
"TransformerFactory"
|
|
33312
33382
|
]);
|
|
33313
|
-
var JAVA_SAFE_EVIDENCE_RE = /(disallow-doctype-decl|external-general-entities|external-parameter-entities|SUPPORT_DTD|ACCESS_EXTERNAL_DTD|ACCESS_EXTERNAL_SCHEMA|setXIncludeAware\s*\(\s*false\s*\)|setExpandEntityReferences\s*\(\s*false\s*\))/;
|
|
33383
|
+
var JAVA_SAFE_EVIDENCE_RE = /(disallow-doctype-decl|external-general-entities|external-parameter-entities|SUPPORT_DTD|ACCESS_EXTERNAL_DTD|ACCESS_EXTERNAL_SCHEMA|load-external-dtd|feature\/secure-processing|FEATURE_SECURE_PROCESSING|jdk\.xml\.(?:totalEntitySizeLimit|entityExpansionLimit|maxGeneralEntitySizeLimit|maxParameterEntitySizeLimit|elementAttributeLimit)|setXIncludeAware\s*\(\s*false\s*\)|setExpandEntityReferences\s*\(\s*false\s*\))/;
|
|
33384
|
+
var JAVA_XML_OUTPUT_ONLY_RE = /\bnew\s+(?:DOMSource|StreamResult)\s*\(/;
|
|
33385
|
+
var JAVA_XML_PARSE_INPUT_RE = /\bnew\s+(?:StreamSource|SAXSource|InputSource)\s*\(/;
|
|
33386
|
+
var JAVA_DOC_BUILDER_NEW_DOCUMENT_RE = /\.\s*newDocument\s*\(\s*\)/;
|
|
33387
|
+
var JAVA_DOC_BUILDER_PARSE_RE = /(?:DocumentBuilder|builder)\s*\.\s*parse\s*\(/;
|
|
33314
33388
|
var PY_LXML_PARSER_INSECURE_DEFAULT_RE = /\bresolve_entities\s*=\s*False\b/;
|
|
33315
33389
|
|
|
33316
33390
|
class XmlEntityExpansionPass {
|
|
@@ -33325,10 +33399,16 @@ class XmlEntityExpansionPass {
|
|
|
33325
33399
|
const safeInFile = JAVA_SAFE_EVIDENCE_RE.test(code);
|
|
33326
33400
|
if (safeInFile)
|
|
33327
33401
|
return { findings };
|
|
33402
|
+
const isXmlOutputOnly = JAVA_XML_OUTPUT_ONLY_RE.test(code) && !JAVA_XML_PARSE_INPUT_RE.test(code);
|
|
33403
|
+
const isDocumentBuilderEmptyOnly = JAVA_DOC_BUILDER_NEW_DOCUMENT_RE.test(code) && !JAVA_DOC_BUILDER_PARSE_RE.test(code);
|
|
33328
33404
|
for (const call of graph.ir.calls) {
|
|
33329
33405
|
const det = this.detectJavaCall(call);
|
|
33330
33406
|
if (!det)
|
|
33331
33407
|
continue;
|
|
33408
|
+
if (det.api === "TransformerFactory" && isXmlOutputOnly)
|
|
33409
|
+
continue;
|
|
33410
|
+
if (det.api === "DocumentBuilderFactory" && isDocumentBuilderEmptyOnly)
|
|
33411
|
+
continue;
|
|
33332
33412
|
const line = call.location.line;
|
|
33333
33413
|
findings.push({ line, language, ...det });
|
|
33334
33414
|
ctx.addFinding({
|
|
@@ -34876,7 +34956,7 @@ var colors = {
|
|
|
34876
34956
|
};
|
|
34877
34957
|
|
|
34878
34958
|
// src/version.ts
|
|
34879
|
-
var version = "3.
|
|
34959
|
+
var version = "3.102.0";
|
|
34880
34960
|
|
|
34881
34961
|
// src/formatters.ts
|
|
34882
34962
|
var SINK_SEVERITY = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.102.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.102.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.5.0",
|