cognium-dev 3.212.0 → 3.214.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 +85 -29
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -12752,31 +12752,33 @@ function findSources(calls, types, patterns, sourceLines, language) {
|
|
|
12752
12752
|
}
|
|
12753
12753
|
}
|
|
12754
12754
|
const RUST_EXTRACTOR_KIND = /(?:^|::)(Json|Form|Query|Path|Extension|Multipart|Body|Bytes)(?:<|$)/;
|
|
12755
|
-
|
|
12756
|
-
for (const
|
|
12757
|
-
for (const
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
|
|
12775
|
-
|
|
12776
|
-
|
|
12777
|
-
|
|
12778
|
-
|
|
12779
|
-
|
|
12755
|
+
if (language === "rust") {
|
|
12756
|
+
for (const type of types) {
|
|
12757
|
+
for (const method of type.methods) {
|
|
12758
|
+
for (const param of method.parameters) {
|
|
12759
|
+
if (!param.type)
|
|
12760
|
+
continue;
|
|
12761
|
+
const kindMatch = RUST_EXTRACTOR_KIND.exec(param.type);
|
|
12762
|
+
if (!kindMatch)
|
|
12763
|
+
continue;
|
|
12764
|
+
const kind = kindMatch[1];
|
|
12765
|
+
if (kind === "Extension")
|
|
12766
|
+
continue;
|
|
12767
|
+
const sourceType = kind === "Form" || kind === "Query" || kind === "Path" ? "http_param" : "http_body";
|
|
12768
|
+
const paramLine = param.line ?? method.start_line;
|
|
12769
|
+
const alreadyExists = sources.some((s) => s.line === paramLine && s.variable === param.name);
|
|
12770
|
+
if (alreadyExists)
|
|
12771
|
+
continue;
|
|
12772
|
+
sources.push({
|
|
12773
|
+
type: sourceType,
|
|
12774
|
+
location: `${param.type} ${param.name} in ${method.name}`,
|
|
12775
|
+
severity: "high",
|
|
12776
|
+
line: paramLine,
|
|
12777
|
+
confidence: 1,
|
|
12778
|
+
variable: param.name,
|
|
12779
|
+
in_method: method.name
|
|
12780
|
+
});
|
|
12781
|
+
}
|
|
12780
12782
|
}
|
|
12781
12783
|
}
|
|
12782
12784
|
}
|
|
@@ -24782,6 +24784,7 @@ class LanguageSourcesPass {
|
|
|
24782
24784
|
additionalSanitizers.push(...findJavaSafeJsonParseSanitizers(code));
|
|
24783
24785
|
additionalSanitizers.push(...findJavaPathNormalizeStartsWithGuardSanitizers(code));
|
|
24784
24786
|
additionalSanitizers.push(...findJavaPathGetFileNameSanitizers(code));
|
|
24787
|
+
additionalSanitizers.push(...findJavaCanonicalPathStartsWithGuardSanitizers(code));
|
|
24785
24788
|
additionalSanitizers.push(...findJavaInlineCrlfStripLogSanitizers(code));
|
|
24786
24789
|
additionalSanitizers.push(...findJavaArgvFormExecSanitizers(code));
|
|
24787
24790
|
for (const finding of findJavaPatternFindings(code, graph.ir.meta.file)) {
|
|
@@ -27638,6 +27641,58 @@ function findJavaPathNormalizeStartsWithGuardSanitizers(code) {
|
|
|
27638
27641
|
}
|
|
27639
27642
|
return sanitizers;
|
|
27640
27643
|
}
|
|
27644
|
+
function findJavaCanonicalPathStartsWithGuardSanitizers(code) {
|
|
27645
|
+
const sanitizers = [];
|
|
27646
|
+
const lines = code.split(`
|
|
27647
|
+
`);
|
|
27648
|
+
const guardRe = /\bif\s*\(\s*!\s*([A-Za-z_]\w*)\s*\.\s*getCanonicalPath\s*\(\s*\)\s*\.\s*startsWith\s*\(/;
|
|
27649
|
+
const terminatorRe = /\b(throw|return)\b/;
|
|
27650
|
+
const assignRe = /^\s*(?:[A-Za-z_][\w.<>[\]]*\s+)?([A-Za-z_]\w*)\s*=(?!=)\s*(.*)$/;
|
|
27651
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
27652
|
+
const m = guardRe.exec(lines[i2]);
|
|
27653
|
+
if (!m)
|
|
27654
|
+
continue;
|
|
27655
|
+
let hasTerminator = terminatorRe.test(lines[i2]);
|
|
27656
|
+
if (!hasTerminator) {
|
|
27657
|
+
for (let j = i2 + 1;j < Math.min(lines.length, i2 + 6); j++) {
|
|
27658
|
+
if (terminatorRe.test(lines[j])) {
|
|
27659
|
+
hasTerminator = true;
|
|
27660
|
+
break;
|
|
27661
|
+
}
|
|
27662
|
+
if (lines[j].includes("}"))
|
|
27663
|
+
break;
|
|
27664
|
+
}
|
|
27665
|
+
}
|
|
27666
|
+
if (!hasTerminator)
|
|
27667
|
+
continue;
|
|
27668
|
+
const guarded = new Set([m[1]]);
|
|
27669
|
+
const mentions = (t) => {
|
|
27670
|
+
for (const n of guarded)
|
|
27671
|
+
if (new RegExp(`\\b${n}\\b`).test(t))
|
|
27672
|
+
return true;
|
|
27673
|
+
return false;
|
|
27674
|
+
};
|
|
27675
|
+
for (let l = 0;l < lines.length; l++) {
|
|
27676
|
+
const lt = lines[l];
|
|
27677
|
+
const a = assignRe.exec(lt);
|
|
27678
|
+
if (a) {
|
|
27679
|
+
if (mentions(a[2]))
|
|
27680
|
+
guarded.add(a[1]);
|
|
27681
|
+
else if (a[1] !== m[1])
|
|
27682
|
+
guarded.delete(a[1]);
|
|
27683
|
+
}
|
|
27684
|
+
if (mentions(lt)) {
|
|
27685
|
+
sanitizers.push({
|
|
27686
|
+
type: "java_canonical_startswith_guard",
|
|
27687
|
+
method: "getCanonicalPath",
|
|
27688
|
+
line: l + 1,
|
|
27689
|
+
sanitizes: ["path_traversal", "external_taint_escape"]
|
|
27690
|
+
});
|
|
27691
|
+
}
|
|
27692
|
+
}
|
|
27693
|
+
}
|
|
27694
|
+
return sanitizers;
|
|
27695
|
+
}
|
|
27641
27696
|
function findJavaPathGetFileNameSanitizers(code) {
|
|
27642
27697
|
const sanitizers = [];
|
|
27643
27698
|
const lines = code.split(`
|
|
@@ -27645,15 +27700,16 @@ function findJavaPathGetFileNameSanitizers(code) {
|
|
|
27645
27700
|
const assignmentRe = /^\s*(?:(?:final\s+)?[A-Za-z_][\w.<>?,\s\[\]]*?\s+)?([A-Za-z_]\w*)\s*=\s*(.+?);\s*$/;
|
|
27646
27701
|
const rhsHasGetFileNameRe = /\.\s*getFileName\s*\(\s*\)/;
|
|
27647
27702
|
const rhsHasPathsChainRe = /\b(?:Paths\s*\.\s*get|Path\s*\.\s*of)\s*\(/;
|
|
27703
|
+
const rhsNewFileGetNameRe = /\bnew\s+File\s*\([\s\S]*\)\s*\.\s*getName\s*\(\s*\)/;
|
|
27648
27704
|
const candidates = [];
|
|
27649
27705
|
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
27650
27706
|
const m = assignmentRe.exec(lines[i2]);
|
|
27651
27707
|
if (!m)
|
|
27652
27708
|
continue;
|
|
27653
27709
|
const rhs = m[2];
|
|
27654
|
-
|
|
27655
|
-
|
|
27656
|
-
if (!
|
|
27710
|
+
const isNioGetFileName = rhsHasGetFileNameRe.test(rhs) && rhsHasPathsChainRe.test(rhs);
|
|
27711
|
+
const isNewFileGetName = rhsNewFileGetNameRe.test(rhs);
|
|
27712
|
+
if (!isNioGetFileName && !isNewFileGetName)
|
|
27657
27713
|
continue;
|
|
27658
27714
|
candidates.push({ line: i2 + 1, boundVar: m[1] });
|
|
27659
27715
|
}
|
|
@@ -47082,7 +47138,7 @@ var colors = {
|
|
|
47082
47138
|
};
|
|
47083
47139
|
|
|
47084
47140
|
// src/version.ts
|
|
47085
|
-
var version = "3.
|
|
47141
|
+
var version = "3.214.0";
|
|
47086
47142
|
|
|
47087
47143
|
// src/formatters.ts
|
|
47088
47144
|
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.214.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.214.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|