cognium-dev 4.9.21 → 4.9.22
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 +88 -19
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -24604,16 +24604,22 @@ class CSharpPlugin extends BaseLanguagePlugin {
|
|
|
24604
24604
|
}
|
|
24605
24605
|
|
|
24606
24606
|
// ../circle-ir/dist/languages/plugins/index.js
|
|
24607
|
+
function createBuiltinPlugins() {
|
|
24608
|
+
return [
|
|
24609
|
+
new JavaPlugin,
|
|
24610
|
+
new JavaScriptPlugin,
|
|
24611
|
+
new PythonPlugin,
|
|
24612
|
+
new RustPlugin,
|
|
24613
|
+
new BashPlugin,
|
|
24614
|
+
new HtmlPlugin,
|
|
24615
|
+
new VuePlugin,
|
|
24616
|
+
new GoPlugin,
|
|
24617
|
+
new CSharpPlugin
|
|
24618
|
+
];
|
|
24619
|
+
}
|
|
24607
24620
|
function registerBuiltinPlugins() {
|
|
24608
|
-
|
|
24609
|
-
|
|
24610
|
-
registerLanguage(new PythonPlugin);
|
|
24611
|
-
registerLanguage(new RustPlugin);
|
|
24612
|
-
registerLanguage(new BashPlugin);
|
|
24613
|
-
registerLanguage(new HtmlPlugin);
|
|
24614
|
-
registerLanguage(new VuePlugin);
|
|
24615
|
-
registerLanguage(new GoPlugin);
|
|
24616
|
-
registerLanguage(new CSharpPlugin);
|
|
24621
|
+
for (const plugin of createBuiltinPlugins())
|
|
24622
|
+
registerLanguage(plugin);
|
|
24617
24623
|
}
|
|
24618
24624
|
// ../circle-ir/dist/analysis/passes/cross-file-pass.js
|
|
24619
24625
|
class CrossFilePass {
|
|
@@ -46991,6 +46997,8 @@ var JAVA_XML_OUTPUT_ONLY_RE = /\bnew\s+(?:DOMSource|StreamResult)\s*\(/;
|
|
|
46991
46997
|
var JAVA_XML_PARSE_INPUT_RE = /\bnew\s+(?:StreamSource|SAXSource|InputSource)\s*\(/;
|
|
46992
46998
|
var JAVA_DOC_BUILDER_NEW_DOCUMENT_RE = /\.\s*newDocument\s*\(\s*\)/;
|
|
46993
46999
|
var JAVA_DOC_BUILDER_PARSE_RE = /(?:DocumentBuilder|builder)\s*\.\s*parse\s*\(/;
|
|
47000
|
+
var JAVA_HARDENING_SETTER_RE = /\.\s*(?:setFeature|setAttribute|setProperty|setXIncludeAware|setExpandEntityReferences)\s*\(/;
|
|
47001
|
+
var JAVA_FACTORY_CHAINED_RE = /\bnewInstance\s*\([^()]*\)\s*\.\s*(?:newDocumentBuilder|newSAXParser|newTransformer|newTemplates|newSchema|createXMLStreamReader|createXMLEventReader)\s*\(/;
|
|
46994
47002
|
var PY_LXML_PARSER_INSECURE_DEFAULT_RE = /\bresolve_entities\s*=\s*False\b/;
|
|
46995
47003
|
|
|
46996
47004
|
class XmlEntityExpansionPass {
|
|
@@ -47003,8 +47011,10 @@ class XmlEntityExpansionPass {
|
|
|
47003
47011
|
const code = ctx.code ?? "";
|
|
47004
47012
|
if (language === "java") {
|
|
47005
47013
|
const safeInFile = JAVA_SAFE_EVIDENCE_RE.test(code);
|
|
47006
|
-
|
|
47007
|
-
|
|
47014
|
+
const processWide = safeInFile && /jdk\.xml\./.test(code);
|
|
47015
|
+
const lines = safeInFile ? code.split(`
|
|
47016
|
+
`) : [];
|
|
47017
|
+
const methodRanges = safeInFile ? this.methodRanges(graph.ir.types) : [];
|
|
47008
47018
|
const isXmlOutputOnly = JAVA_XML_OUTPUT_ONLY_RE.test(code) && !JAVA_XML_PARSE_INPUT_RE.test(code);
|
|
47009
47019
|
const isDocumentBuilderEmptyOnly = JAVA_DOC_BUILDER_NEW_DOCUMENT_RE.test(code) && !JAVA_DOC_BUILDER_PARSE_RE.test(code);
|
|
47010
47020
|
for (const call of graph.ir.calls) {
|
|
@@ -47016,6 +47026,8 @@ class XmlEntityExpansionPass {
|
|
|
47016
47026
|
if (det.api === "DocumentBuilderFactory" && isDocumentBuilderEmptyOnly)
|
|
47017
47027
|
continue;
|
|
47018
47028
|
const line = call.location.line;
|
|
47029
|
+
if (safeInFile && (processWide || !this.isProvablyUnhardened(lines, line, methodRanges, det.api)))
|
|
47030
|
+
continue;
|
|
47019
47031
|
findings.push({ line, language, ...det });
|
|
47020
47032
|
ctx.addFinding({
|
|
47021
47033
|
id: `${this.name}-${file}-${line}-${det.api}`,
|
|
@@ -47025,11 +47037,11 @@ class XmlEntityExpansionPass {
|
|
|
47025
47037
|
cwe: det.cwe,
|
|
47026
47038
|
severity: "high",
|
|
47027
47039
|
level: "error",
|
|
47028
|
-
message: `${det.api} created without disabling DTD / external-entity ` + "processing. Vulnerable to
|
|
47040
|
+
message: `${det.api} created without disabling DTD / external-entity ` + "processing. Vulnerable to external-entity disclosure " + "(CWE-611) and billion-laughs / quadratic blow-up DoS " + '(CWE-776). Add `setFeature("http://apache.org/xml/features/' + 'disallow-doctype-decl", true)` (or the equivalent) before ' + "parsing.",
|
|
47029
47041
|
file,
|
|
47030
47042
|
line,
|
|
47031
47043
|
fix: this.fixForJava(det.api),
|
|
47032
|
-
evidence: { ...det, language, safeFeatureInFile:
|
|
47044
|
+
evidence: { ...det, language, safeFeatureInFile: safeInFile }
|
|
47033
47045
|
});
|
|
47034
47046
|
}
|
|
47035
47047
|
return { findings };
|
|
@@ -47052,7 +47064,7 @@ class XmlEntityExpansionPass {
|
|
|
47052
47064
|
cwe: det.cwe,
|
|
47053
47065
|
severity: "high",
|
|
47054
47066
|
level: "error",
|
|
47055
|
-
message: `${det.api} called without an entity-safe parser. Vulnerable ` + "to billion-laughs / quadratic blow-up DoS (CWE-776)
|
|
47067
|
+
message: `${det.api} called without an entity-safe parser. Vulnerable ` + (det.cwe === "CWE-611" ? "to external-entity disclosure (CWE-611) and billion-laughs / " + "quadratic blow-up DoS (CWE-776). " : "to billion-laughs / quadratic blow-up DoS (CWE-776). ") + "Use `defusedxml` or pass " + "an `XMLParser(resolve_entities=False)` to lxml.",
|
|
47056
47068
|
file,
|
|
47057
47069
|
line,
|
|
47058
47070
|
fix: this.fixForPython(det.api),
|
|
@@ -47063,6 +47075,63 @@ class XmlEntityExpansionPass {
|
|
|
47063
47075
|
}
|
|
47064
47076
|
return { findings };
|
|
47065
47077
|
}
|
|
47078
|
+
methodRanges(types) {
|
|
47079
|
+
const out2 = [];
|
|
47080
|
+
for (const t of types ?? []) {
|
|
47081
|
+
for (const m of t.methods ?? []) {
|
|
47082
|
+
if (typeof m.start_line === "number" && typeof m.end_line === "number")
|
|
47083
|
+
out2.push([m.start_line, m.end_line]);
|
|
47084
|
+
}
|
|
47085
|
+
}
|
|
47086
|
+
return out2;
|
|
47087
|
+
}
|
|
47088
|
+
isProvablyUnhardened(lines, line, methodRanges, api) {
|
|
47089
|
+
let range = null;
|
|
47090
|
+
for (const r of methodRanges) {
|
|
47091
|
+
if (line < r[0] || line > r[1])
|
|
47092
|
+
continue;
|
|
47093
|
+
if (!range || r[1] - r[0] < range[1] - range[0])
|
|
47094
|
+
range = r;
|
|
47095
|
+
}
|
|
47096
|
+
if (!range)
|
|
47097
|
+
return false;
|
|
47098
|
+
let decl = "";
|
|
47099
|
+
let declEnd = line;
|
|
47100
|
+
for (;declEnd <= Math.min(line + 3, range[1]); declEnd++) {
|
|
47101
|
+
decl += " " + (lines[declEnd - 1] ?? "").trim();
|
|
47102
|
+
if (decl.includes(";"))
|
|
47103
|
+
break;
|
|
47104
|
+
}
|
|
47105
|
+
const body2 = lines.slice(line - 1, range[1]).join(`
|
|
47106
|
+
`);
|
|
47107
|
+
if (api === "TransformerFactory" && !/\bnew\s+StreamSource\s*\(/.test(body2))
|
|
47108
|
+
return false;
|
|
47109
|
+
if (JAVA_HARDENING_SETTER_RE.test(body2))
|
|
47110
|
+
return false;
|
|
47111
|
+
const chained = JAVA_FACTORY_CHAINED_RE.exec(decl);
|
|
47112
|
+
if (chained) {
|
|
47113
|
+
const prod = /[\w>\]]\s+([A-Za-z_$][\w$]*)\s*=/.exec(decl);
|
|
47114
|
+
if (!prod)
|
|
47115
|
+
return true;
|
|
47116
|
+
const pn = prod[1].replace(/\$/g, "\\$");
|
|
47117
|
+
const after = lines.slice(declEnd, range[1]).join(`
|
|
47118
|
+
`);
|
|
47119
|
+
return !new RegExp(`[(,]\\s*${pn}\\s*[,)]|\\breturn\\s+${pn}\\s*;`).test(after);
|
|
47120
|
+
}
|
|
47121
|
+
const m = /[\w>\]]\s+([A-Za-z_$][\w$]*)\s*=\s*[\w.]*\bnewInstance\s*\([^()]*\)\s*;/.exec(decl);
|
|
47122
|
+
if (!m)
|
|
47123
|
+
return false;
|
|
47124
|
+
const name2 = m[1].replace(/\$/g, "\\$");
|
|
47125
|
+
const rest = lines.slice(declEnd, range[1]).join(`
|
|
47126
|
+
`);
|
|
47127
|
+
const builds = new RegExp(`\\b${name2}\\s*\\.\\s*(?:newDocumentBuilder|newSAXParser|newTransformer|newTemplates|newSchema|createXMLStreamReader|createXMLEventReader)\\s*\\(`);
|
|
47128
|
+
if (!builds.test(rest))
|
|
47129
|
+
return false;
|
|
47130
|
+
const escapes = new RegExp(`[(,]\\s*${name2}\\s*[,)]|\\breturn\\s+${name2}\\s*;`);
|
|
47131
|
+
if (escapes.test(rest))
|
|
47132
|
+
return false;
|
|
47133
|
+
return true;
|
|
47134
|
+
}
|
|
47066
47135
|
detectJavaCall(call) {
|
|
47067
47136
|
if (call.method_name !== "newInstance")
|
|
47068
47137
|
return null;
|
|
@@ -47073,7 +47142,7 @@ class XmlEntityExpansionPass {
|
|
|
47073
47142
|
return {
|
|
47074
47143
|
pattern: `${factory}.newInstance()`,
|
|
47075
47144
|
api: factory,
|
|
47076
|
-
cwe: "CWE-
|
|
47145
|
+
cwe: "CWE-611"
|
|
47077
47146
|
};
|
|
47078
47147
|
}
|
|
47079
47148
|
}
|
|
@@ -47086,7 +47155,7 @@ class XmlEntityExpansionPass {
|
|
|
47086
47155
|
return {
|
|
47087
47156
|
pattern: `etree.${method}`,
|
|
47088
47157
|
api: `lxml.etree.${method}`,
|
|
47089
|
-
cwe: "CWE-
|
|
47158
|
+
cwe: "CWE-611"
|
|
47090
47159
|
};
|
|
47091
47160
|
}
|
|
47092
47161
|
if ((method === "parse" || method === "fromstring") && (recv === "ET" || recv === "ElementTree" || recv.endsWith(".ElementTree"))) {
|
|
@@ -49777,7 +49846,7 @@ var colors = {
|
|
|
49777
49846
|
};
|
|
49778
49847
|
|
|
49779
49848
|
// src/version.ts
|
|
49780
|
-
var version = "4.9.
|
|
49849
|
+
var version = "4.9.22";
|
|
49781
49850
|
|
|
49782
49851
|
// src/formatters.ts
|
|
49783
49852
|
var LIBRARY_API_SURFACE_TAG2 = "library-api-surface:caller-responsibility";
|
|
@@ -50322,8 +50391,8 @@ function generateSarifResults(results, crossFileData) {
|
|
|
50322
50391
|
|
|
50323
50392
|
// src/build-info.ts
|
|
50324
50393
|
var buildInfo = {
|
|
50325
|
-
gitSha: "
|
|
50326
|
-
builtAt: "2026-09-
|
|
50394
|
+
gitSha: "54a142d",
|
|
50395
|
+
builtAt: "2026-09-22T01:39:02.544Z"
|
|
50327
50396
|
};
|
|
50328
50397
|
|
|
50329
50398
|
// src/utils/args.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.22",
|
|
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",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@cognium/project-profile-detect": "1.1.1",
|
|
70
|
-
"circle-ir": "4.9.
|
|
70
|
+
"circle-ir": "4.9.22"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@types/node": "^26.6.1",
|