cognium-dev 3.134.0 → 3.135.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.
Files changed (2) hide show
  1. package/dist/cli.js +88 -1
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -22709,6 +22709,9 @@ class LanguageSourcesPass {
22709
22709
  for (const finding of findJavaMongoNosqlInjectionFindings(code, graph.ir.meta.file)) {
22710
22710
  ctx.addFinding(finding);
22711
22711
  }
22712
+ for (const finding of findJavaUrlOpenStreamSsrfFindings(code, graph.ir.meta.file)) {
22713
+ ctx.addFinding(finding);
22714
+ }
22712
22715
  }
22713
22716
  if (language === "python" || language === "javascript" || language === "typescript" || language === "go") {
22714
22717
  const exfilFindings = findExternalSecretExfiltrationFindings(code, graph.ir.meta.file, language);
@@ -26949,6 +26952,90 @@ function findPythonMongoengineWhereNosqlInjectionFindings(code, file) {
26949
26952
  }
26950
26953
  return findings;
26951
26954
  }
26955
+ function findJavaUrlOpenStreamSsrfFindings(code, file) {
26956
+ const findings = [];
26957
+ if (typeof code !== "string" || code.length === 0)
26958
+ return findings;
26959
+ if (!/\bnew\s+URL\s*\(/.test(code) && !/\bURI\s*\.\s*create\s*\(/.test(code)) {
26960
+ return findings;
26961
+ }
26962
+ if (!/\.\s*(?:openStream|openConnection|getContent)\s*\(/.test(code)) {
26963
+ return findings;
26964
+ }
26965
+ const lines = code.split(`
26966
+ `);
26967
+ const reqExtractRe = /\b\w+\s*\.\s*(?:getParameter|getParameterValues|getHeader|getHeaders|getCookies|getReader|getQueryString|getRequestURI|getInputStream|getPart|getParts)\s*\(/;
26968
+ const taintedVars = new Set;
26969
+ for (let pass = 0;pass < 3; pass++) {
26970
+ const before = taintedVars.size;
26971
+ for (let i2 = 0;i2 < lines.length; i2++) {
26972
+ const t = lines[i2].trim();
26973
+ const a = t.match(/^(?:final\s+)?(?:[\w<>?,\[\]]+\s+)?(\w+)\s*=\s*(.+?);?$/);
26974
+ if (!a)
26975
+ continue;
26976
+ const lhs = a[1];
26977
+ const rhs = a[2];
26978
+ if (taintedVars.has(lhs))
26979
+ continue;
26980
+ if (reqExtractRe.test(rhs)) {
26981
+ taintedVars.add(lhs);
26982
+ continue;
26983
+ }
26984
+ for (const v of taintedVars) {
26985
+ if (new RegExp(`\\b${v}\\b`).test(rhs)) {
26986
+ taintedVars.add(lhs);
26987
+ break;
26988
+ }
26989
+ }
26990
+ }
26991
+ if (taintedVars.size === before)
26992
+ break;
26993
+ }
26994
+ if (taintedVars.size === 0)
26995
+ return findings;
26996
+ const sinkRe = /\.\s*(openStream|openConnection|getContent)\s*\(/;
26997
+ const seen = new Set;
26998
+ for (let i2 = 0;i2 < lines.length; i2++) {
26999
+ const line = lines[i2];
27000
+ const m = line.match(sinkRe);
27001
+ if (!m)
27002
+ continue;
27003
+ const op = m[1];
27004
+ const sinkIdx = line.indexOf(`.${op}`);
27005
+ if (sinkIdx < 0)
27006
+ continue;
27007
+ const head = line.substring(0, sinkIdx + 1);
27008
+ let tainted = reqExtractRe.test(head);
27009
+ if (!tainted) {
27010
+ for (const v of taintedVars) {
27011
+ if (new RegExp(`\\b${v}\\b`).test(head)) {
27012
+ tainted = true;
27013
+ break;
27014
+ }
27015
+ }
27016
+ }
27017
+ if (!tainted)
27018
+ continue;
27019
+ const key = `${i2 + 1}:${op}`;
27020
+ if (seen.has(key))
27021
+ continue;
27022
+ seen.add(key);
27023
+ findings.push({
27024
+ id: `ssrf-${file}-${i2 + 1}-java-url-${op.toLowerCase()}`,
27025
+ pass: "language-sources",
27026
+ category: "security",
27027
+ rule_id: "ssrf",
27028
+ cwe: "CWE-918",
27029
+ severity: "critical",
27030
+ level: "error",
27031
+ message: `SSRF: Java \`URL.${op}()\` invoked on a URL derived from servlet ` + 'request input. Even when an `if (url.startsWith("https://"))` ' + "guard is present, the host portion remains attacker-controlled — " + "use a strict host allowlist (parse the URL, check `getHost()`) " + "before issuing the request.",
27032
+ file,
27033
+ line: i2 + 1,
27034
+ snippet: line.trim()
27035
+ });
27036
+ }
27037
+ return findings;
27038
+ }
26952
27039
 
26953
27040
  // ../circle-ir/dist/analysis/passes/sink-filter-pass.js
26954
27041
  var JS_XSS_SANITIZERS = [
@@ -40076,7 +40163,7 @@ var colors = {
40076
40163
  };
40077
40164
 
40078
40165
  // src/version.ts
40079
- var version = "3.134.0";
40166
+ var version = "3.135.0";
40080
40167
 
40081
40168
  // src/formatters.ts
40082
40169
  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.134.0",
3
+ "version": "3.135.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.134.0"
69
+ "circle-ir": "^3.135.0"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/node": "^25.5.0",