cognium-dev 3.95.0 → 3.97.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 +130 -1
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -12125,6 +12125,126 @@ var CWE_78_RECEIVER_ALLOWLIST = new Set([
12125
12125
  "ProcessExecutor",
12126
12126
  "RuntimeUtil"
12127
12127
  ]);
12128
+ function isFunctionCallbackArgument(arg) {
12129
+ if (arg.literal !== null && arg.literal !== undefined)
12130
+ return false;
12131
+ const expr = (arg.expression ?? "").trim();
12132
+ if (expr.length === 0)
12133
+ return false;
12134
+ const body2 = expr.startsWith("async ") ? expr.slice(6).trimStart() : expr;
12135
+ if (body2.startsWith("("))
12136
+ return true;
12137
+ if (/^function\b/.test(body2))
12138
+ return true;
12139
+ return false;
12140
+ }
12141
+ function findGoLocalDeclaredType(varName, callLine, sourceLines) {
12142
+ if (!varName)
12143
+ return null;
12144
+ const WINDOW = 50;
12145
+ const startIdx = Math.max(0, callLine - 2);
12146
+ const endIdx = Math.max(0, startIdx - WINDOW);
12147
+ const name2 = varName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12148
+ const VAR_DECL_RE = new RegExp(`^\\s*var\\s+${name2}\\s+([^=\\n][^\\n]*)$`);
12149
+ const VAR_INIT_RE = new RegExp(`^\\s*var\\s+${name2}(?:\\s+[^=\\n]*?)?\\s*=\\s*(.+)$`);
12150
+ const SHORT_INIT_RE = new RegExp(`^\\s*${name2}\\s*:=\\s*(.+)$`);
12151
+ for (let i2 = startIdx;i2 >= endIdx; i2--) {
12152
+ const raw = sourceLines[i2];
12153
+ if (raw === undefined)
12154
+ continue;
12155
+ const line = raw.replace(/\/\/.*$/, "").trimEnd();
12156
+ let m = VAR_DECL_RE.exec(line);
12157
+ if (m) {
12158
+ return { kind: "typed-decl", text: m[1].trim() };
12159
+ }
12160
+ m = VAR_INIT_RE.exec(line);
12161
+ if (m) {
12162
+ return classifyGoRhs(m[1].trim());
12163
+ }
12164
+ m = SHORT_INIT_RE.exec(line);
12165
+ if (m) {
12166
+ return classifyGoRhs(m[1].trim());
12167
+ }
12168
+ }
12169
+ return null;
12170
+ }
12171
+ function classifyGoRhs(rhs) {
12172
+ const body2 = rhs.startsWith("&") ? rhs.slice(1).trimStart() : rhs;
12173
+ if (/^make\s*\(/.test(body2)) {
12174
+ return { kind: "untyped" };
12175
+ }
12176
+ const parenIdx = body2.indexOf("(");
12177
+ const braceIdx = body2.indexOf("{");
12178
+ if (parenIdx >= 0 && (braceIdx < 0 || parenIdx < braceIdx)) {
12179
+ return { kind: "untyped" };
12180
+ }
12181
+ if (braceIdx > 0) {
12182
+ const tag = body2.slice(0, braceIdx).trim();
12183
+ if (tag.length > 0) {
12184
+ if (/\binterface\s*\{\s*\}/.test(tag))
12185
+ return { kind: "untyped" };
12186
+ if (/\bany\b/.test(tag))
12187
+ return { kind: "untyped" };
12188
+ return { kind: "typed-init", text: tag };
12189
+ }
12190
+ }
12191
+ return { kind: "untyped" };
12192
+ }
12193
+ function classifyGoDestinationType(decl) {
12194
+ if (decl === null)
12195
+ return "unknown";
12196
+ if (decl.kind === "untyped")
12197
+ return "unknown";
12198
+ const text = decl.text;
12199
+ if (/\binterface\s*\{\s*\}/.test(text))
12200
+ return "unsafe";
12201
+ if (/\bany\b/.test(text))
12202
+ return "unsafe";
12203
+ return "safe";
12204
+ }
12205
+ function isSafeGoJsonUnmarshalCall(call, pattern, language, sourceLines) {
12206
+ if (language !== "go")
12207
+ return false;
12208
+ if (pattern.type !== "deserialization")
12209
+ return false;
12210
+ if (!sourceLines)
12211
+ return false;
12212
+ const method = call.method_name;
12213
+ let destPos;
12214
+ if (method === "Unmarshal" && pattern.class === "json") {
12215
+ destPos = 1;
12216
+ } else if (method === "Decode" && pattern.class === "Decoder") {
12217
+ destPos = 0;
12218
+ } else {
12219
+ return false;
12220
+ }
12221
+ const destArg = call.arguments.find((a) => a.position === destPos);
12222
+ if (!destArg)
12223
+ return false;
12224
+ const expr = (destArg.expression ?? "").trim();
12225
+ if (expr.length === 0)
12226
+ return false;
12227
+ if (expr.startsWith("&")) {
12228
+ const inner = expr.slice(1).trimStart();
12229
+ const compIdx = inner.indexOf("{");
12230
+ if (compIdx > 0) {
12231
+ const decl2 = { kind: "typed-init", text: inner.slice(0, compIdx).trim() };
12232
+ return classifyGoDestinationType(decl2) === "safe";
12233
+ }
12234
+ const m = /^&([A-Za-z_]\w*)$/.exec(expr);
12235
+ if (!m)
12236
+ return false;
12237
+ const varName = m[1];
12238
+ const decl = findGoLocalDeclaredType(varName, call.location.line, sourceLines);
12239
+ return classifyGoDestinationType(decl) === "safe";
12240
+ }
12241
+ const idMatch = /^([A-Za-z_]\w*)$/.exec(expr);
12242
+ if (idMatch) {
12243
+ const decl = findGoLocalDeclaredType(idMatch[1], call.location.line, sourceLines);
12244
+ return classifyGoDestinationType(decl) === "safe";
12245
+ }
12246
+ return false;
12247
+ }
12128
12248
  function findSinks(calls, patterns, typeHierarchy, language, sourceLines) {
12129
12249
  const sinkMap = new Map;
12130
12250
  for (const call of calls) {
@@ -12157,6 +12277,15 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines) {
12157
12277
  }
12158
12278
  }
12159
12279
  }
12280
+ if (pattern.type === "code_injection" && (call.method_name === "setInterval" || call.method_name === "setTimeout")) {
12281
+ const firstArg = call.arguments.find((a) => a.position === 0);
12282
+ if (firstArg && isFunctionCallbackArgument(firstArg)) {
12283
+ continue;
12284
+ }
12285
+ }
12286
+ if (isSafeGoJsonUnmarshalCall(call, pattern, language, sourceLines)) {
12287
+ continue;
12288
+ }
12160
12289
  const location = formatCallLocation(call);
12161
12290
  const key = `${location}:${call.location.line}:${pattern.cwe}`;
12162
12291
  const confidence = calculateSinkConfidence(call, pattern);
@@ -34579,7 +34708,7 @@ var colors = {
34579
34708
  };
34580
34709
 
34581
34710
  // src/version.ts
34582
- var version = "3.95.0";
34711
+ var version = "3.97.0";
34583
34712
 
34584
34713
  // src/formatters.ts
34585
34714
  var SINK_SEVERITY = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "3.95.0",
3
+ "version": "3.97.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",
@@ -65,7 +65,7 @@
65
65
  "registry": "https://registry.npmjs.org/"
66
66
  },
67
67
  "dependencies": {
68
- "circle-ir": "^3.95.0"
68
+ "circle-ir": "^3.97.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.5.0",