cognium-dev 3.159.0 → 3.161.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 +98 -8
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -11520,7 +11520,24 @@ var DEFAULT_SINKS = [
|
|
|
11520
11520
|
{ method: "outerHTML", type: "xss", cwe: "CWE-79", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
11521
11521
|
{ method: "unserialize", class: "serialize", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
11522
11522
|
{ method: "unserialize", class: "node-serialize", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
11523
|
-
{ method: "unserialize", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] }
|
|
11523
|
+
{ method: "unserialize", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
11524
|
+
{ method: "get", class: "httpx", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
11525
|
+
{ method: "post", class: "httpx", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
11526
|
+
{ method: "request", class: "httpx", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [1] },
|
|
11527
|
+
{ method: "stream", class: "httpx", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [1] },
|
|
11528
|
+
{ method: "delete", class: "httpx", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
11529
|
+
{ method: "put", class: "httpx", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
11530
|
+
{ method: "patch", class: "httpx", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
11531
|
+
{ method: "head", class: "httpx", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
11532
|
+
{ method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
11533
|
+
{ method: "fetch", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
11534
|
+
{ method: "fetchrow", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
11535
|
+
{ method: "fetchval", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
11536
|
+
{ method: "fetchrow", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
11537
|
+
{ method: "fetchval", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
11538
|
+
{ method: "Redirect", class: "http", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [2], languages: ["go"] },
|
|
11539
|
+
{ method: "Do", class: "Client", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["go"] },
|
|
11540
|
+
{ method: "DoTimeout", class: "Client", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["go"] }
|
|
11524
11541
|
];
|
|
11525
11542
|
var DEFAULT_SANITIZERS = [
|
|
11526
11543
|
{ method: "setString", class: "PreparedStatement", removes: ["sql_injection"] },
|
|
@@ -12982,7 +12999,10 @@ function matchesSinkPattern(call, pattern, typeHierarchy, language) {
|
|
|
12982
12999
|
return true;
|
|
12983
13000
|
}
|
|
12984
13001
|
const subtypeArgArityOk = !pattern.arg_positions || pattern.arg_positions.length === 0 || pattern.arg_positions.every((pos) => pos < (call.arguments?.length ?? 0));
|
|
12985
|
-
if (call.receiver_type && call.receiver_type === pattern.class) {} else if (call.receiver_type && typeHierarchy && subtypeArgArityOk && typeHierarchy.isSubtypeOf(call.receiver_type, pattern.class)) {} else if (call.receiver_type_fqn && call.receiver_type_fqn.endsWith("." + pattern.class)) {} else if (call.receiver_type_fqn && typeHierarchy && subtypeArgArityOk && typeHierarchy.isSubtypeOf(call.receiver_type_fqn, pattern.class)) {} else if (call.
|
|
13002
|
+
if (call.receiver_type && call.receiver_type === pattern.class) {} else if (call.receiver_type && typeHierarchy && subtypeArgArityOk && typeHierarchy.isSubtypeOf(call.receiver_type, pattern.class)) {} else if (call.receiver_type_fqn && call.receiver_type_fqn.endsWith("." + pattern.class)) {} else if (call.receiver_type_fqn && typeHierarchy && subtypeArgArityOk && typeHierarchy.isSubtypeOf(call.receiver_type_fqn, pattern.class)) {} else if (!call.receiver_type && !call.receiver_type_fqn && call.receiver && typeHierarchy && subtypeArgArityOk && (() => {
|
|
13003
|
+
const factoryReturn = typeHierarchy.resolveFactoryReturnType(call.receiver);
|
|
13004
|
+
return factoryReturn !== null && typeHierarchy.isSubtypeOf(factoryReturn, pattern.class);
|
|
13005
|
+
})()) {} else if (call.receiver && !receiverMightBeClass(call.receiver, pattern.class)) {
|
|
12986
13006
|
if (typeHierarchy && typeHierarchy.couldBeType(call.receiver, pattern.class)) {
|
|
12987
13007
|
return true;
|
|
12988
13008
|
}
|
|
@@ -13055,7 +13075,7 @@ function receiverMightBeClass(receiver, className) {
|
|
|
13055
13075
|
}
|
|
13056
13076
|
const lowerReceiver = receiver.toLowerCase();
|
|
13057
13077
|
const lowerClass = className.toLowerCase();
|
|
13058
|
-
if (lowerReceiver
|
|
13078
|
+
if (lowerReceiver === lowerClass || lowerReceiver.endsWith("." + lowerClass)) {
|
|
13059
13079
|
return true;
|
|
13060
13080
|
}
|
|
13061
13081
|
if (receiver.includes(".") && !receiver.endsWith(")")) {
|
|
@@ -13915,6 +13935,7 @@ class TypeHierarchyResolver {
|
|
|
13915
13935
|
implementations = new Map;
|
|
13916
13936
|
_subtypeCache = new Map;
|
|
13917
13937
|
_implCache = new Map;
|
|
13938
|
+
factoryReturnTypes = new Map;
|
|
13918
13939
|
addFromIR(ir, filePath) {
|
|
13919
13940
|
for (const type of ir.types) {
|
|
13920
13941
|
this.addType(type, filePath, ir.meta.package || null);
|
|
@@ -14120,11 +14141,22 @@ class TypeHierarchyResolver {
|
|
|
14120
14141
|
getAllTypes() {
|
|
14121
14142
|
return Array.from(this.types.values());
|
|
14122
14143
|
}
|
|
14144
|
+
registerFactoryReturnType(factoryClass, method, returnFqn) {
|
|
14145
|
+
this.factoryReturnTypes.set(`${factoryClass}.${method}`, returnFqn);
|
|
14146
|
+
}
|
|
14147
|
+
resolveFactoryReturnType(receiver) {
|
|
14148
|
+
const m = receiver.match(/(?:^|\.)([A-Z]\w*)\.(\w+)\(\)$/);
|
|
14149
|
+
if (!m)
|
|
14150
|
+
return null;
|
|
14151
|
+
const key = `${m[1]}.${m[2]}`;
|
|
14152
|
+
return this.factoryReturnTypes.get(key) ?? null;
|
|
14153
|
+
}
|
|
14123
14154
|
clear() {
|
|
14124
14155
|
this.types.clear();
|
|
14125
14156
|
this.nameToFqn.clear();
|
|
14126
14157
|
this.subtypes.clear();
|
|
14127
14158
|
this.implementations.clear();
|
|
14159
|
+
this.factoryReturnTypes.clear();
|
|
14128
14160
|
}
|
|
14129
14161
|
resolveTypeName(name2, currentPackage) {
|
|
14130
14162
|
if (name2.includes("."))
|
|
@@ -14463,6 +14495,9 @@ function registerCommonLibraries(resolver) {
|
|
|
14463
14495
|
for (const type of [...apacheHttpClient4x, ...apacheHttpClient5x]) {
|
|
14464
14496
|
resolver.addType(type, "common-libraries", type.package);
|
|
14465
14497
|
}
|
|
14498
|
+
resolver.registerFactoryReturnType("HttpClients", "createDefault", "org.apache.http.impl.client.CloseableHttpClient");
|
|
14499
|
+
resolver.registerFactoryReturnType("HttpClients", "createSystem", "org.apache.http.impl.client.CloseableHttpClient");
|
|
14500
|
+
resolver.registerFactoryReturnType("HttpClients", "createMinimal", "org.apache.http.impl.client.MinimalHttpClient");
|
|
14466
14501
|
}
|
|
14467
14502
|
// ../circle-ir/dist/resolution/symbol-table.js
|
|
14468
14503
|
class SymbolTable {
|
|
@@ -21961,6 +21996,30 @@ class GoPlugin extends BaseLanguagePlugin {
|
|
|
21961
21996
|
severity: "high",
|
|
21962
21997
|
argPositions: [0, 2]
|
|
21963
21998
|
},
|
|
21999
|
+
{
|
|
22000
|
+
method: "Get",
|
|
22001
|
+
class: "fasthttp",
|
|
22002
|
+
type: "ssrf",
|
|
22003
|
+
cwe: "CWE-918",
|
|
22004
|
+
severity: "high",
|
|
22005
|
+
argPositions: [1]
|
|
22006
|
+
},
|
|
22007
|
+
{
|
|
22008
|
+
method: "Post",
|
|
22009
|
+
class: "fasthttp",
|
|
22010
|
+
type: "ssrf",
|
|
22011
|
+
cwe: "CWE-918",
|
|
22012
|
+
severity: "high",
|
|
22013
|
+
argPositions: [1]
|
|
22014
|
+
},
|
|
22015
|
+
{
|
|
22016
|
+
method: "GetTimeout",
|
|
22017
|
+
class: "fasthttp",
|
|
22018
|
+
type: "ssrf",
|
|
22019
|
+
cwe: "CWE-918",
|
|
22020
|
+
severity: "high",
|
|
22021
|
+
argPositions: [1]
|
|
22022
|
+
},
|
|
21964
22023
|
{
|
|
21965
22024
|
method: "Unmarshal",
|
|
21966
22025
|
class: "json",
|
|
@@ -29828,6 +29887,12 @@ function correlateDollarBraceToArgPositions(method, refs) {
|
|
|
29828
29887
|
}
|
|
29829
29888
|
}
|
|
29830
29889
|
});
|
|
29890
|
+
const declaredNameToIndex = new Map;
|
|
29891
|
+
method.parameters.forEach((param, idx) => {
|
|
29892
|
+
if (param.name && !declaredNameToIndex.has(param.name)) {
|
|
29893
|
+
declaredNameToIndex.set(param.name, idx);
|
|
29894
|
+
}
|
|
29895
|
+
});
|
|
29831
29896
|
const positions = new Set;
|
|
29832
29897
|
for (const ref of refs) {
|
|
29833
29898
|
const namedIdx = paramNameToIndex.get(ref);
|
|
@@ -29835,6 +29900,11 @@ function correlateDollarBraceToArgPositions(method, refs) {
|
|
|
29835
29900
|
positions.add(namedIdx);
|
|
29836
29901
|
continue;
|
|
29837
29902
|
}
|
|
29903
|
+
const declaredIdx = declaredNameToIndex.get(ref);
|
|
29904
|
+
if (declaredIdx !== undefined) {
|
|
29905
|
+
positions.add(declaredIdx);
|
|
29906
|
+
continue;
|
|
29907
|
+
}
|
|
29838
29908
|
const positionalIdx = parsePositionalRef(ref);
|
|
29839
29909
|
if (positionalIdx !== null && positionalIdx < method.parameters.length) {
|
|
29840
29910
|
positions.add(positionalIdx);
|
|
@@ -29865,11 +29935,11 @@ class MyBatisAnnotationSqlSinkPass {
|
|
|
29865
29935
|
category = "security";
|
|
29866
29936
|
run(ctx) {
|
|
29867
29937
|
if (ctx.language !== "java") {
|
|
29868
|
-
return { annotatedMethodCount: 0, addedSinkCount: 0 };
|
|
29938
|
+
return { annotatedMethodCount: 0, addedSinkCount: 0, declarationFindingCount: 0 };
|
|
29869
29939
|
}
|
|
29870
29940
|
const { types, imports, calls } = ctx.graph.ir;
|
|
29871
29941
|
if (!fileImportsMyBatis(imports)) {
|
|
29872
|
-
return { annotatedMethodCount: 0, addedSinkCount: 0 };
|
|
29942
|
+
return { annotatedMethodCount: 0, addedSinkCount: 0, declarationFindingCount: 0 };
|
|
29873
29943
|
}
|
|
29874
29944
|
const mapperMethods = [];
|
|
29875
29945
|
for (const type of types) {
|
|
@@ -29898,6 +29968,7 @@ class MyBatisAnnotationSqlSinkPass {
|
|
|
29898
29968
|
interfaceSimpleName: type.name,
|
|
29899
29969
|
interfaceFqn,
|
|
29900
29970
|
methodName: method.name,
|
|
29971
|
+
declarationLine: method.start_line,
|
|
29901
29972
|
taintedArgPositions: positions
|
|
29902
29973
|
});
|
|
29903
29974
|
}
|
|
@@ -29905,9 +29976,27 @@ class MyBatisAnnotationSqlSinkPass {
|
|
|
29905
29976
|
if (mapperMethods.length === 0) {
|
|
29906
29977
|
return {
|
|
29907
29978
|
annotatedMethodCount: 0,
|
|
29908
|
-
addedSinkCount: 0
|
|
29979
|
+
addedSinkCount: 0,
|
|
29980
|
+
declarationFindingCount: 0
|
|
29909
29981
|
};
|
|
29910
29982
|
}
|
|
29983
|
+
const file = ctx.graph.ir.meta.file;
|
|
29984
|
+
let declarationFindingCount = 0;
|
|
29985
|
+
for (const rec of mapperMethods) {
|
|
29986
|
+
ctx.addFinding({
|
|
29987
|
+
id: `${this.name}-${file}-${rec.declarationLine}-${rec.methodName}`,
|
|
29988
|
+
pass: this.name,
|
|
29989
|
+
category: this.category,
|
|
29990
|
+
rule_id: this.name,
|
|
29991
|
+
cwe: "CWE-89",
|
|
29992
|
+
severity: "critical",
|
|
29993
|
+
level: "error",
|
|
29994
|
+
message: `MyBatis Mapper method \`${rec.interfaceSimpleName}.${rec.methodName}\` uses raw ` + `\`\${}\` interpolation in its @Select/@Update/@Insert/@Delete annotation. ` + `Any caller passing dynamic input into arg position(s) ` + `${rec.taintedArgPositions.join(", ")} will execute unbound SQL (CWE-89). ` + `Replace \`\${x}\` with \`#{x}\` to enable JDBC parameter binding.`,
|
|
29995
|
+
file,
|
|
29996
|
+
line: rec.declarationLine
|
|
29997
|
+
});
|
|
29998
|
+
declarationFindingCount++;
|
|
29999
|
+
}
|
|
29911
30000
|
const sinks = ctx.hasResult("taint-matcher") ? ctx.getResult("taint-matcher").sinks : ctx.graph.ir.taint.sinks;
|
|
29912
30001
|
let addedSinkCount = 0;
|
|
29913
30002
|
for (const call of calls) {
|
|
@@ -29935,7 +30024,8 @@ class MyBatisAnnotationSqlSinkPass {
|
|
|
29935
30024
|
}
|
|
29936
30025
|
return {
|
|
29937
30026
|
annotatedMethodCount: mapperMethods.length,
|
|
29938
|
-
addedSinkCount
|
|
30027
|
+
addedSinkCount,
|
|
30028
|
+
declarationFindingCount
|
|
29939
30029
|
};
|
|
29940
30030
|
}
|
|
29941
30031
|
}
|
|
@@ -43751,7 +43841,7 @@ var colors = {
|
|
|
43751
43841
|
};
|
|
43752
43842
|
|
|
43753
43843
|
// src/version.ts
|
|
43754
|
-
var version = "3.
|
|
43844
|
+
var version = "3.161.0";
|
|
43755
43845
|
|
|
43756
43846
|
// src/formatters.ts
|
|
43757
43847
|
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.161.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.161.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|