cognium-dev 3.112.0 → 3.114.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 +89 -10
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -11165,6 +11165,7 @@ var DEFAULT_SINKS = [
11165
11165
  { method: "exec", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["python"] },
11166
11166
  { method: "compile", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
11167
11167
  { method: "__import__", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
11168
+ { method: "import_module", class: "importlib", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
11168
11169
  { method: "loads", class: "pickle", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["python"] },
11169
11170
  { method: "load", class: "pickle", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["python"] },
11170
11171
  { method: "loads", class: "marshal", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["python"] },
@@ -11348,6 +11349,12 @@ var DEFAULT_SINKS = [
11348
11349
  { method: "log!", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0, 1, 2] },
11349
11350
  { method: "println!", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0, 1, 2] },
11350
11351
  { method: "eprintln!", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0, 1, 2] },
11352
+ { method: "log::info!", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0, 1, 2], languages: ["rust"] },
11353
+ { method: "log::warn!", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0, 1, 2], languages: ["rust"] },
11354
+ { method: "log::error!", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0, 1, 2], languages: ["rust"] },
11355
+ { method: "log::debug!", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0, 1, 2], languages: ["rust"] },
11356
+ { method: "log::trace!", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0, 1, 2], languages: ["rust"] },
11357
+ { method: "log::log!", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0, 1, 2], languages: ["rust"] },
11351
11358
  { method: "query", class: "sqlx", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11352
11359
  { method: "query_as", class: "sqlx", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11353
11360
  { method: "query_as", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
@@ -13349,7 +13356,7 @@ function canSourceReachSink(sourceType, sinkType) {
13349
13356
  http_cookie: ["sql_injection", "xss", "mybatis_mapper_call", "code_injection", "crlf"],
13350
13357
  http_path: ["path_traversal", "sql_injection", "ssrf", "mybatis_mapper_call"],
13351
13358
  http_query: ["sql_injection", "command_injection", "xss", "ssrf", "mybatis_mapper_call", "code_injection", "crlf", "mass_assignment"],
13352
- io_input: ["command_injection", "path_traversal", "deserialization", "xxe", "code_injection", "xss"],
13359
+ io_input: ["command_injection", "path_traversal", "deserialization", "xxe", "code_injection", "xss", "ssrf"],
13353
13360
  env_input: ["command_injection", "path_traversal"],
13354
13361
  db_input: ["xss", "sql_injection"],
13355
13362
  file_input: ["deserialization", "xxe", "path_traversal", "command_injection", "code_injection"],
@@ -20487,14 +20494,14 @@ class BashPlugin extends BaseLanguagePlugin {
20487
20494
  type: "ssrf",
20488
20495
  cwe: "CWE-918",
20489
20496
  severity: "high",
20490
- argPositions: [0]
20497
+ argPositions: []
20491
20498
  },
20492
20499
  {
20493
20500
  method: "wget",
20494
20501
  type: "ssrf",
20495
20502
  cwe: "CWE-918",
20496
20503
  severity: "high",
20497
- argPositions: [0]
20504
+ argPositions: []
20498
20505
  },
20499
20506
  {
20500
20507
  method: "source",
@@ -23084,7 +23091,14 @@ var BASH_UNTRUSTED_ENV_PATTERNS = [
23084
23091
  /^CONTENT_LENGTH$/i,
23085
23092
  /^PATH_INFO$/i,
23086
23093
  /^SCRIPT_NAME$/i,
23087
- /^SERVER_NAME$/i
23094
+ /^SERVER_NAME$/i,
23095
+ /^RPC_/i,
23096
+ /^XMLRPC/i,
23097
+ /^JSONRPC/i,
23098
+ /^CMD_/i,
23099
+ /^EXEC_/i,
23100
+ /^EVAL_/i,
23101
+ /^SHELL_/i
23088
23102
  ];
23089
23103
  var BASH_NETWORK_COMMANDS = new Set(["curl", "wget", "nc", "ncat"]);
23090
23104
  var BASH_FILE_COMMANDS = new Set(["cat", "head", "tail", "less", "more", "awk", "sed", "cut", "grep"]);
@@ -31691,6 +31705,9 @@ var PY_SECURE_TRUE_RE = /\bsecure\s*=\s*True\b/;
31691
31705
  var PY_HTTPONLY_TRUE_RE = /\bhttponly\s*=\s*True\b/i;
31692
31706
  var JAVA_SET_SECURE_TRUE_RE = /\.setSecure\s*\(\s*true\s*\)/;
31693
31707
  var JAVA_SET_HTTPONLY_TRUE_RE = /\.setHttpOnly\s*\(\s*true\s*\)/;
31708
+ var GO_SECURE_TRUE_RE = /\bSecure\s*:\s*true\b/;
31709
+ var GO_HTTPONLY_TRUE_RE = /\bHttpOnly\s*:\s*true\b/;
31710
+ var RUST_SET_COOKIE_MACRO_RE = /(format!|write!|writeln!)\s*\(([^()]*Set-Cookie[^()]*)\)/gis;
31694
31711
 
31695
31712
  class InsecureCookiePass {
31696
31713
  name = "insecure-cookie";
@@ -31725,6 +31742,20 @@ class InsecureCookiePass {
31725
31742
  insecureCookies.push(det);
31726
31743
  this.emit(ctx, file, det, "java");
31727
31744
  }
31745
+ } else if (language === "go") {
31746
+ for (const call of graph.ir.calls) {
31747
+ const det = this.detectGo(call);
31748
+ if (!det)
31749
+ continue;
31750
+ insecureCookies.push(det);
31751
+ this.emit(ctx, file, det, "go");
31752
+ }
31753
+ } else if (language === "rust") {
31754
+ const dets = this.detectRustSetCookieFormat(code);
31755
+ for (const det of dets) {
31756
+ insecureCookies.push(det);
31757
+ this.emit(ctx, file, det, "rust");
31758
+ }
31728
31759
  }
31729
31760
  return { insecureCookies };
31730
31761
  }
@@ -31792,13 +31823,61 @@ class InsecureCookiePass {
31792
31823
  optionsPresent: false
31793
31824
  };
31794
31825
  }
31826
+ detectGo(call) {
31827
+ if (call.method_name !== "SetCookie")
31828
+ return null;
31829
+ if ((call.receiver ?? "") !== "http")
31830
+ return null;
31831
+ if (call.arguments.length < 2)
31832
+ return null;
31833
+ const cookieArg = call.arguments.find((a) => a.position === 1);
31834
+ const cookieExpr = (cookieArg?.expression ?? "").trim();
31835
+ if (!cookieExpr.includes("{") || !cookieExpr.includes("}"))
31836
+ return null;
31837
+ const missingSecure = !GO_SECURE_TRUE_RE.test(cookieExpr);
31838
+ const missingHttpOnly = !GO_HTTPONLY_TRUE_RE.test(cookieExpr);
31839
+ if (!missingSecure && !missingHttpOnly)
31840
+ return null;
31841
+ return {
31842
+ line: call.location.line,
31843
+ receiver: "http.SetCookie",
31844
+ missingSecure,
31845
+ missingHttpOnly,
31846
+ optionsPresent: true
31847
+ };
31848
+ }
31849
+ detectRustSetCookieFormat(code) {
31850
+ const out2 = [];
31851
+ const re = new RegExp(RUST_SET_COOKIE_MACRO_RE.source, RUST_SET_COOKIE_MACRO_RE.flags);
31852
+ let m;
31853
+ while ((m = re.exec(code)) !== null) {
31854
+ const macro = m[1] ?? "";
31855
+ const body2 = m[2] ?? "";
31856
+ const missingSecure = !/\bSecure\b/.test(body2);
31857
+ const missingHttpOnly = !/\bHttpOnly\b/.test(body2);
31858
+ if (!missingSecure && !missingHttpOnly)
31859
+ continue;
31860
+ const line = code.slice(0, m.index).split(`
31861
+ `).length;
31862
+ out2.push({
31863
+ line,
31864
+ receiver: macro,
31865
+ missingSecure,
31866
+ missingHttpOnly,
31867
+ optionsPresent: true
31868
+ });
31869
+ }
31870
+ return out2;
31871
+ }
31795
31872
  emit(ctx, file, det, flavor) {
31796
31873
  const missing = [];
31797
- if (det.missingSecure)
31798
- missing.push(flavor === "js" ? "`secure: true`" : flavor === "python" ? "`secure=True`" : "`setSecure(true)`");
31799
- if (det.missingHttpOnly)
31800
- missing.push(flavor === "js" ? "`httpOnly: true`" : flavor === "python" ? "`httponly=True`" : "`setHttpOnly(true)`");
31801
- const fix = flavor === "js" ? 'Pass `{ secure: true, httpOnly: true, sameSite: "lax" }` as the third argument to `res.cookie()`.' : flavor === "python" ? 'Pass `secure=True, httponly=True, samesite="Lax"` to `response.set_cookie(...)`.' : "After constructing the cookie, call `cookie.setSecure(true)` and `cookie.setHttpOnly(true)` before adding it to the response.";
31874
+ if (det.missingSecure) {
31875
+ missing.push(flavor === "js" ? "`secure: true`" : flavor === "python" ? "`secure=True`" : flavor === "java" ? "`setSecure(true)`" : flavor === "go" ? "`Secure: true`" : "`Secure` attribute");
31876
+ }
31877
+ if (det.missingHttpOnly) {
31878
+ missing.push(flavor === "js" ? "`httpOnly: true`" : flavor === "python" ? "`httponly=True`" : flavor === "java" ? "`setHttpOnly(true)`" : flavor === "go" ? "`HttpOnly: true`" : "`HttpOnly` attribute");
31879
+ }
31880
+ const fix = flavor === "js" ? 'Pass `{ secure: true, httpOnly: true, sameSite: "lax" }` as the third argument to `res.cookie()`.' : flavor === "python" ? 'Pass `secure=True, httponly=True, samesite="Lax"` to `response.set_cookie(...)`.' : flavor === "java" ? "After constructing the cookie, call `cookie.setSecure(true)` and `cookie.setHttpOnly(true)` before adding it to the response." : flavor === "go" ? "Set `Secure: true` and `HttpOnly: true` on the `http.Cookie` struct literal passed to `http.SetCookie`." : "Append `; Secure; HttpOnly` to the `Set-Cookie` header string.";
31802
31881
  ctx.addFinding({
31803
31882
  id: `${this.name}-${file}-${det.line}`,
31804
31883
  pass: this.name,
@@ -36701,7 +36780,7 @@ var colors = {
36701
36780
  };
36702
36781
 
36703
36782
  // src/version.ts
36704
- var version = "3.112.0";
36783
+ var version = "3.114.0";
36705
36784
 
36706
36785
  // src/formatters.ts
36707
36786
  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.112.0",
3
+ "version": "3.114.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.112.0"
69
+ "circle-ir": "^3.114.0"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/node": "^25.5.0",