cognium-dev 3.178.0 → 3.179.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 +117 -6
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -11683,12 +11683,20 @@ var DEFAULT_SINKS = [
|
|
|
11683
11683
|
{ method: "format", class: "String", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
11684
11684
|
{ method: "format", class: "Formatter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
11685
11685
|
{ method: "printf", class: "System.out", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
11686
|
+
{ method: "format", class: "MessageFormat", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
11687
|
+
{ method: "printf", class: "PrintStream", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
11688
|
+
{ method: "format", class: "PrintStream", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
11689
|
+
{ method: "printf", class: "PrintWriter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
11690
|
+
{ method: "format", class: "PrintWriter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
11686
11691
|
{ method: "printf", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
11687
11692
|
{ method: "fprintf", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [1], languages: ["python"] },
|
|
11688
11693
|
{ method: "Sprintf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
11689
11694
|
{ method: "Printf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
11690
11695
|
{ method: "Errorf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
11691
11696
|
{ method: "Fprintf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [1], languages: ["go"] },
|
|
11697
|
+
{ method: "Printf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
11698
|
+
{ method: "Fatalf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
11699
|
+
{ method: "Panicf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
11692
11700
|
{ method: "setHeader", type: "crlf", cwe: "CWE-113", severity: "medium", arg_positions: [1], languages: ["javascript", "typescript"] },
|
|
11693
11701
|
{ method: "writeHead", type: "crlf", cwe: "CWE-113", severity: "medium", arg_positions: [2], languages: ["javascript", "typescript"] },
|
|
11694
11702
|
{ method: "cookie", type: "crlf", cwe: "CWE-113", severity: "medium", arg_positions: [1], languages: ["javascript", "typescript"] },
|
|
@@ -13680,6 +13688,11 @@ function calculateSinkConfidence(call, pattern) {
|
|
|
13680
13688
|
if (pattern.class && call.receiver) {
|
|
13681
13689
|
if (receiverMightBeClass(call.receiver, pattern.class)) {
|
|
13682
13690
|
confidence += 0.1;
|
|
13691
|
+
const receiverLc = call.receiver.toLowerCase();
|
|
13692
|
+
const classLc = pattern.class.toLowerCase();
|
|
13693
|
+
if (call.receiver === pattern.class || receiverLc === classLc) {
|
|
13694
|
+
confidence += 0.05;
|
|
13695
|
+
}
|
|
13683
13696
|
}
|
|
13684
13697
|
}
|
|
13685
13698
|
if (pattern.severity === "critical") {
|
|
@@ -32655,6 +32668,85 @@ function resolveFastjsonFromPom(pomXml) {
|
|
|
32655
32668
|
}
|
|
32656
32669
|
return null;
|
|
32657
32670
|
}
|
|
32671
|
+
function resolveFastjsonFromGradle(buildGradle) {
|
|
32672
|
+
if (!buildGradle)
|
|
32673
|
+
return null;
|
|
32674
|
+
const directRe = /['"(]\s*com\.alibaba:fastjson:([^'"$\s)]+)\s*['")]/;
|
|
32675
|
+
const direct = buildGradle.match(directRe);
|
|
32676
|
+
if (direct) {
|
|
32677
|
+
const version2 = direct[1];
|
|
32678
|
+
return { version: version2, noneAutotype: /_noneautotype/i.test(version2) };
|
|
32679
|
+
}
|
|
32680
|
+
const propRefRe = /['"(]\s*com\.alibaba:fastjson:\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?\s*['")]/;
|
|
32681
|
+
const propRef = buildGradle.match(propRefRe);
|
|
32682
|
+
if (!propRef)
|
|
32683
|
+
return null;
|
|
32684
|
+
const propName = propRef[1];
|
|
32685
|
+
const defRe = new RegExp(`\\b${propName}\\s*[=:]\\s*['"]([^'"\\s]+)['"]`);
|
|
32686
|
+
const def = buildGradle.match(defRe);
|
|
32687
|
+
if (!def)
|
|
32688
|
+
return null;
|
|
32689
|
+
const version = def[1];
|
|
32690
|
+
return { version, noneAutotype: /_noneautotype/i.test(version) };
|
|
32691
|
+
}
|
|
32692
|
+
function resolvePyYamlFromRequirements(requirementsTxt) {
|
|
32693
|
+
if (!requirementsTxt)
|
|
32694
|
+
return null;
|
|
32695
|
+
for (const rawLine of requirementsTxt.split(/\r?\n/)) {
|
|
32696
|
+
const line = rawLine.replace(/#.*$/, "").trim();
|
|
32697
|
+
if (!line)
|
|
32698
|
+
continue;
|
|
32699
|
+
if (line.startsWith("-"))
|
|
32700
|
+
continue;
|
|
32701
|
+
const m = line.match(/^(pyyaml)\s*(==|>=|~=|>|===)\s*(\d+(?:\.\d+)*)/i);
|
|
32702
|
+
if (!m)
|
|
32703
|
+
continue;
|
|
32704
|
+
const version = m[3];
|
|
32705
|
+
return { version, safeByDefault: isPyYamlVersionSafeByDefault(version) };
|
|
32706
|
+
}
|
|
32707
|
+
return null;
|
|
32708
|
+
}
|
|
32709
|
+
function resolvePyYamlFromPyproject(pyprojectToml) {
|
|
32710
|
+
if (!pyprojectToml)
|
|
32711
|
+
return null;
|
|
32712
|
+
const poetryLine = pyprojectToml.match(/^\s*(pyyaml)\s*=\s*"([\^~=<>]*)(\d+(?:\.\d+)*)"/im);
|
|
32713
|
+
if (poetryLine) {
|
|
32714
|
+
const version = poetryLine[3];
|
|
32715
|
+
return { version, safeByDefault: isPyYamlVersionSafeByDefault(version) };
|
|
32716
|
+
}
|
|
32717
|
+
const poetryTable = pyprojectToml.match(/^\s*(pyyaml)\s*=\s*\{[^}]*\bversion\s*=\s*"([\^~=<>]*)(\d+(?:\.\d+)*)"/im);
|
|
32718
|
+
if (poetryTable) {
|
|
32719
|
+
const version = poetryTable[3];
|
|
32720
|
+
return { version, safeByDefault: isPyYamlVersionSafeByDefault(version) };
|
|
32721
|
+
}
|
|
32722
|
+
const pep621 = pyprojectToml.match(/"(pyyaml)\s*(==|>=|~=|>|===)\s*(\d+(?:\.\d+)*)/i);
|
|
32723
|
+
if (pep621) {
|
|
32724
|
+
const version = pep621[3];
|
|
32725
|
+
return { version, safeByDefault: isPyYamlVersionSafeByDefault(version) };
|
|
32726
|
+
}
|
|
32727
|
+
return null;
|
|
32728
|
+
}
|
|
32729
|
+
function isPyYamlVersionSafeByDefault(version) {
|
|
32730
|
+
const parts2 = version.split(".").map((s) => Number.parseInt(s, 10));
|
|
32731
|
+
if (parts2.length === 0 || !Number.isFinite(parts2[0]))
|
|
32732
|
+
return false;
|
|
32733
|
+
return parts2[0] >= 6;
|
|
32734
|
+
}
|
|
32735
|
+
function fileHasUnsafePyYamlLoader(sourceLines, sinkLine) {
|
|
32736
|
+
const start2 = Math.max(0, sinkLine - 1);
|
|
32737
|
+
const end = Math.min(sourceLines.length, start2 + 10);
|
|
32738
|
+
const unsafeRe = /\bLoader\s*=\s*(?:yaml\s*\.\s*)?(?:Loader|UnsafeLoader|FullLoader)\b/;
|
|
32739
|
+
for (let i2 = start2;i2 < end; i2++) {
|
|
32740
|
+
const ln = sourceLines[i2] ?? "";
|
|
32741
|
+
if (unsafeRe.test(ln))
|
|
32742
|
+
return true;
|
|
32743
|
+
const stripped = ln.trim();
|
|
32744
|
+
if (i2 > start2 && (stripped === ")" || stripped.endsWith(")"))) {
|
|
32745
|
+
return false;
|
|
32746
|
+
}
|
|
32747
|
+
}
|
|
32748
|
+
return false;
|
|
32749
|
+
}
|
|
32658
32750
|
function fileReenablesFastjsonAutotype(source) {
|
|
32659
32751
|
if (!source)
|
|
32660
32752
|
return false;
|
|
@@ -32688,6 +32780,8 @@ var JACKSON_METHODS = new Set(["readValue", "convertValue", "treeToValue"]);
|
|
|
32688
32780
|
var JACKSON_CLASSES = new Set(["ObjectMapper", "ObjectReader"]);
|
|
32689
32781
|
var SNAKEYAML_METHODS = new Set(["load", "loadAs", "loadAll"]);
|
|
32690
32782
|
var SNAKEYAML_CLASSES = new Set(["Yaml"]);
|
|
32783
|
+
var PYYAML_METHODS = new Set(["load"]);
|
|
32784
|
+
var PYYAML_CLASSES = new Set(["yaml"]);
|
|
32691
32785
|
|
|
32692
32786
|
class DeserializationSafetyGatePass {
|
|
32693
32787
|
dependencyContext;
|
|
@@ -32698,18 +32792,31 @@ class DeserializationSafetyGatePass {
|
|
|
32698
32792
|
}
|
|
32699
32793
|
run(ctx) {
|
|
32700
32794
|
const { graph, language, code } = ctx;
|
|
32701
|
-
if (language !== "java") {
|
|
32702
|
-
return { droppedFastjson: 0, droppedJackson: 0, droppedSnakeYaml: 0 };
|
|
32795
|
+
if (language !== "java" && language !== "python") {
|
|
32796
|
+
return { droppedFastjson: 0, droppedJackson: 0, droppedSnakeYaml: 0, droppedPyYaml: 0 };
|
|
32703
32797
|
}
|
|
32704
32798
|
const sinks = ctx.hasResult("sink-filter") ? ctx.getResult("sink-filter").sinks : graph.ir.taint.sinks;
|
|
32705
32799
|
const pomXml = this.dependencyContext?.java?.pomXml;
|
|
32706
|
-
const
|
|
32800
|
+
const buildGradle = this.dependencyContext?.java?.buildGradle;
|
|
32801
|
+
const fastjson = (pomXml ? resolveFastjsonFromPom(pomXml) : null) ?? (buildGradle ? resolveFastjsonFromGradle(buildGradle) : null);
|
|
32707
32802
|
const fastjsonHardened = fastjson?.noneAutotype === true && !fileReenablesFastjsonAutotype(code);
|
|
32708
32803
|
const jacksonSafe = !fileEnablesJacksonPolymorphism(code);
|
|
32709
32804
|
const snakeYamlSafe = fileConfiguresSnakeYamlSafely(code);
|
|
32805
|
+
const requirementsTxt = this.dependencyContext?.python?.requirementsTxt;
|
|
32806
|
+
const pyprojectToml = this.dependencyContext?.python?.pyprojectToml;
|
|
32807
|
+
const pyYaml = (requirementsTxt ? resolvePyYamlFromRequirements(requirementsTxt) : null) ?? (pyprojectToml ? resolvePyYamlFromPyproject(pyprojectToml) : null);
|
|
32808
|
+
const pyYamlSafeByDefault = pyYaml?.safeByDefault === true;
|
|
32809
|
+
let sourceLines = null;
|
|
32810
|
+
const getSourceLines = () => {
|
|
32811
|
+
if (sourceLines === null)
|
|
32812
|
+
sourceLines = code.split(`
|
|
32813
|
+
`);
|
|
32814
|
+
return sourceLines;
|
|
32815
|
+
};
|
|
32710
32816
|
let droppedFastjson = 0;
|
|
32711
32817
|
let droppedJackson = 0;
|
|
32712
32818
|
let droppedSnakeYaml = 0;
|
|
32819
|
+
let droppedPyYaml = 0;
|
|
32713
32820
|
const kept = sinks.filter((sink) => {
|
|
32714
32821
|
if (sink.type !== "deserialization")
|
|
32715
32822
|
return true;
|
|
@@ -32727,14 +32834,18 @@ class DeserializationSafetyGatePass {
|
|
|
32727
32834
|
droppedSnakeYaml++;
|
|
32728
32835
|
return false;
|
|
32729
32836
|
}
|
|
32837
|
+
if (language === "python" && pyYamlSafeByDefault && PYYAML_METHODS.has(sink.method) && (sink.class === undefined || PYYAML_CLASSES.has(sink.class)) && !fileHasUnsafePyYamlLoader(getSourceLines(), sink.line)) {
|
|
32838
|
+
droppedPyYaml++;
|
|
32839
|
+
return false;
|
|
32840
|
+
}
|
|
32730
32841
|
return true;
|
|
32731
32842
|
});
|
|
32732
|
-
const totalDropped = droppedFastjson + droppedJackson + droppedSnakeYaml;
|
|
32843
|
+
const totalDropped = droppedFastjson + droppedJackson + droppedSnakeYaml + droppedPyYaml;
|
|
32733
32844
|
if (totalDropped > 0) {
|
|
32734
32845
|
sinks.length = 0;
|
|
32735
32846
|
sinks.push(...kept);
|
|
32736
32847
|
}
|
|
32737
|
-
return { droppedFastjson, droppedJackson, droppedSnakeYaml };
|
|
32848
|
+
return { droppedFastjson, droppedJackson, droppedSnakeYaml, droppedPyYaml };
|
|
32738
32849
|
}
|
|
32739
32850
|
}
|
|
32740
32851
|
|
|
@@ -45224,7 +45335,7 @@ var colors = {
|
|
|
45224
45335
|
};
|
|
45225
45336
|
|
|
45226
45337
|
// src/version.ts
|
|
45227
|
-
var version = "3.
|
|
45338
|
+
var version = "3.179.0";
|
|
45228
45339
|
|
|
45229
45340
|
// src/formatters.ts
|
|
45230
45341
|
var LIBRARY_API_SURFACE_TAG2 = "library-api-surface:caller-responsibility";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.179.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",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
68
|
"@cognium/project-profile-detect": "^1.1.0",
|
|
69
|
-
"circle-ir": "^3.
|
|
69
|
+
"circle-ir": "^3.179.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|