circle-ir 3.71.0 → 3.72.1

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.
@@ -12018,6 +12018,41 @@ var DEFAULT_SINKS = [
12018
12018
  // pattern with a language-scoped classless entry. The method name
12019
12019
  // `redirect` is rare outside HTTP frameworks so the FP risk is low.
12020
12020
  { method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["javascript", "typescript"] },
12021
+ // Node.js LDAP Injection (ldapjs) — CWE-90
12022
+ // cognium-dev#104 Sprint 22: receiver matches the canonical ldapjs
12023
+ // import name (`const ldap = require('ldapjs')` → ldap.search/...).
12024
+ { method: "search", class: "ldap", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
12025
+ { method: "searchSync", class: "ldap", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
12026
+ { method: "search", class: "ldapjs", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
12027
+ { method: "searchSync", class: "ldapjs", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
12028
+ // Node.js XPath Injection (xpath module) — CWE-643
12029
+ // cognium-dev#104 Sprint 22: `const xpath = require('xpath')` → xpath.select/select1/evaluate.
12030
+ { method: "select", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
12031
+ { method: "select1", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
12032
+ { method: "evaluate", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
12033
+ { method: "parse", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
12034
+ // Node.js XXE (libxmljs, xmldom) — CWE-611
12035
+ // cognium-dev#104 Sprint 22: `const libxml = require('libxmljs')` (or 'libxml')
12036
+ // → libxml.parseXml(src, {noent: true}). xmldom DOMParser via parseFromString.
12037
+ { method: "parseXml", class: "libxml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
12038
+ { method: "parseXmlString", class: "libxml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
12039
+ { method: "parseXml", class: "libxmljs", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
12040
+ { method: "parseXmlString", class: "libxmljs", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
12041
+ { method: "parseFromString", class: "DOMParser", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
12042
+ { method: "parseFromString", class: "xmldom", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
12043
+ // Node.js Server-Side Template Injection (SSTI) — CWE-94
12044
+ // cognium-dev#104 Sprint 22: ejs/handlebars/pug template render with
12045
+ // tainted templates → arbitrary JS execution. Uses `code_injection`
12046
+ // SinkType to mirror the Python Jinja2/Mako pattern above.
12047
+ { method: "render", class: "ejs", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
12048
+ { method: "compile", class: "ejs", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
12049
+ { method: "render", class: "handlebars", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
12050
+ { method: "compile", class: "handlebars", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
12051
+ { method: "render", class: "pug", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
12052
+ { method: "compile", class: "pug", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
12053
+ { method: "render", class: "mustache", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
12054
+ { method: "render", class: "nunjucks", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
12055
+ { method: "renderString", class: "nunjucks", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
12021
12056
  // =========================================================================
12022
12057
  // Python Sinks
12023
12058
  // =========================================================================
@@ -12127,6 +12162,16 @@ var DEFAULT_SINKS = [
12127
12162
  { method: "delete_one", class: "Collection", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0] },
12128
12163
  { method: "delete_many", class: "Collection", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0] },
12129
12164
  { method: "aggregate", class: "Collection", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0] },
12165
+ // pymongo dynamic attribute-access pattern: `db.users.find({...})` — receiver
12166
+ // class isn't statically known. Method-only entries restricted to Python.
12167
+ // cognium-dev#104 Sprint 22.
12168
+ { method: "find_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
12169
+ { method: "update_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0, 1], languages: ["python"] },
12170
+ { method: "update_many", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0, 1], languages: ["python"] },
12171
+ { method: "delete_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
12172
+ { method: "delete_many", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
12173
+ { method: "replace_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0, 1], languages: ["python"] },
12174
+ { method: "count_documents", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
12130
12175
  // Python Template Injection (Jinja2, Mako)
12131
12176
  { method: "from_string", class: "Template", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
12132
12177
  { method: "Template", class: "jinja2", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
@@ -12137,6 +12182,15 @@ var DEFAULT_SINKS = [
12137
12182
  { method: "error", class: "logger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
12138
12183
  { method: "debug", class: "logger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
12139
12184
  { method: "critical", class: "logger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
12185
+ // Python `logging` module top-level functions (e.g. logging.info(...))
12186
+ // — cognium-dev#104 Sprint 22: OOP fixtures use `import logging; logging.info(self.msg)`.
12187
+ { method: "info", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
12188
+ { method: "warning", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
12189
+ { method: "error", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
12190
+ { method: "debug", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
12191
+ { method: "critical", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
12192
+ { method: "log", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [1] },
12193
+ { method: "exception", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
12140
12194
  // =========================================================================
12141
12195
  // Java CWE-Bench Enhancement Patterns (Collection/Builder)
12142
12196
  // =========================================================================
@@ -18361,6 +18415,9 @@ function isFalsePositive(result, sinkLine, taintedVar) {
18361
18415
  if (varValue && varValue.type !== "unknown" && !result.tainted.has(taintedVar)) {
18362
18416
  return { isFalsePositive: true, reason: `variable_is_constant: ${varValue.value}` };
18363
18417
  }
18418
+ if (taintedVar.startsWith("self.") || taintedVar.startsWith("this.")) {
18419
+ return { isFalsePositive: false, reason: null };
18420
+ }
18364
18421
  if (result.symbols.has(taintedVar) && !result.tainted.has(taintedVar)) {
18365
18422
  return { isFalsePositive: true, reason: "variable_not_tainted" };
18366
18423
  }
@@ -22495,13 +22552,16 @@ function findGetterSources(types, instanceFieldTaint, _sourceCode) {
22495
22552
  return sources;
22496
22553
  }
22497
22554
  function findOopFieldReadSources(types, sourceCode, language) {
22498
- if (language !== "java" && language !== "python") return [];
22555
+ if (language !== "java" && language !== "python" && language !== "javascript" && language !== "typescript") return [];
22499
22556
  const sources = [];
22500
22557
  const lines = sourceCode.split("\n");
22501
22558
  const isPython = language === "python";
22559
+ const isJs = language === "javascript" || language === "typescript";
22560
+ const isJava = language === "java";
22502
22561
  const SELF = isPython ? "self" : "this";
22503
22562
  const javaHttpPattern = /\b(?:req|request|httpRequest|servletRequest|httpServletRequest)\.(?:getParameter|getParameterValues|getParameterMap|getHeader|getHeaders|getCookies|getQueryString|getPathInfo|getRequestURI|getRequestURL|getInputStream|getReader)\b/;
22504
22563
  const fieldAssignRe = new RegExp(`^\\s*${SELF}\\.([A-Za-z_]\\w*)\\s*=\\s*(.+?)(?:;\\s*)?$`);
22564
+ const fieldAssignReG = new RegExp(`${SELF}\\.([A-Za-z_]\\w*)\\s*=\\s*([^;}\\n]+)`, "g");
22505
22565
  const commentPrefix = isPython ? "#" : "//";
22506
22566
  for (const type of types) {
22507
22567
  if (type.kind !== "class") continue;
@@ -22513,7 +22573,12 @@ function findOopFieldReadSources(types, sourceCode, language) {
22513
22573
  ctor = m;
22514
22574
  break;
22515
22575
  }
22516
- } else {
22576
+ } else if (isJs) {
22577
+ if (m.name === "constructor") {
22578
+ ctor = m;
22579
+ break;
22580
+ }
22581
+ } else if (isJava) {
22517
22582
  if (m.name === type.name) {
22518
22583
  ctor = m;
22519
22584
  break;
@@ -22532,25 +22597,41 @@ function findOopFieldReadSources(types, sourceCode, language) {
22532
22597
  for (let i2 = ctorStart - 1; i2 < Math.min(ctorEnd, lines.length); i2++) {
22533
22598
  const line = lines[i2] ?? "";
22534
22599
  if (line.trim().startsWith(commentPrefix)) continue;
22535
- const m = line.match(fieldAssignRe);
22536
- if (!m) continue;
22537
- const fieldName = m[1];
22538
- const rhs = m[2].trim().replace(/;\s*$/, "");
22539
- let sourceType = null;
22540
- if (paramNames.has(rhs)) {
22541
- sourceType = "interprocedural_param";
22542
- } else if (!isPython && javaHttpPattern.test(rhs)) {
22543
- sourceType = "http_param";
22544
- } else if (isPython) {
22545
- for (const { pattern, type: type2 } of PYTHON_TAINTED_PATTERNS2) {
22546
- if (pattern.test(rhs)) {
22547
- sourceType = type2;
22548
- break;
22600
+ const pairs = [];
22601
+ const anchored = line.match(fieldAssignRe);
22602
+ if (anchored) pairs.push({ field: anchored[1], rhs: anchored[2].trim().replace(/;\s*$/, "") });
22603
+ if (isJs) {
22604
+ for (const m of line.matchAll(fieldAssignReG)) {
22605
+ const field = m[1];
22606
+ const rhs = m[2].trim().replace(/;\s*$/, "");
22607
+ if (!pairs.some((p) => p.field === field)) pairs.push({ field, rhs });
22608
+ }
22609
+ }
22610
+ if (pairs.length === 0) continue;
22611
+ for (const { field: fieldName, rhs } of pairs) {
22612
+ let sourceType = null;
22613
+ if (paramNames.has(rhs)) {
22614
+ sourceType = "interprocedural_param";
22615
+ } else if (isJava && javaHttpPattern.test(rhs)) {
22616
+ sourceType = "http_param";
22617
+ } else if (isPython) {
22618
+ for (const { pattern, type: type2 } of PYTHON_TAINTED_PATTERNS2) {
22619
+ if (pattern.test(rhs)) {
22620
+ sourceType = type2;
22621
+ break;
22622
+ }
22623
+ }
22624
+ } else if (isJs) {
22625
+ for (const { pattern, type: type2 } of JS_TAINTED_PATTERNS) {
22626
+ if (pattern.test(rhs)) {
22627
+ sourceType = type2;
22628
+ break;
22629
+ }
22549
22630
  }
22550
22631
  }
22551
- }
22552
- if (sourceType) {
22553
- fieldTaint.set(fieldName, { line: i2 + 1, type: sourceType });
22632
+ if (sourceType) {
22633
+ fieldTaint.set(fieldName, { line: i2 + 1, type: sourceType });
22634
+ }
22554
22635
  }
22555
22636
  }
22556
22637
  if (fieldTaint.size === 0) continue;
@@ -23339,12 +23420,22 @@ var SinkFilterPass = class {
23339
23420
  if (language === "python") {
23340
23421
  const { pyTaintedVars, pySanitizedVars } = langSources;
23341
23422
  const sourceLines = ctx.code.split("\n");
23423
+ const oopFieldVars = /* @__PURE__ */ new Set();
23424
+ for (const s of sources) {
23425
+ if (s.variable && s.variable.startsWith("self.")) {
23426
+ oopFieldVars.add(s.variable);
23427
+ }
23428
+ }
23342
23429
  filtered = filtered.filter((sink) => {
23343
23430
  if (sink.type !== "xpath_injection") return true;
23344
23431
  const sinkLineText = sourceLines[sink.line - 1] ?? "";
23345
23432
  const taintedVarOnLine = [...pyTaintedVars.keys()].find(
23346
23433
  (v) => new RegExp(`\\b${v}\\b`).test(sinkLineText)
23347
23434
  );
23435
+ const oopVarOnLine = [...oopFieldVars].find(
23436
+ (v) => sinkLineText.includes(v)
23437
+ );
23438
+ if (oopVarOnLine) return true;
23348
23439
  if (!taintedVarOnLine) return false;
23349
23440
  if (pySanitizedVars.has(taintedVarOnLine)) return false;
23350
23441
  if (new RegExp(`\\.xpath\\s*\\([^)]*\\b\\w+\\s*=\\s*\\b${taintedVarOnLine}\\b`).test(sinkLineText)) return false;
@@ -11400,6 +11400,41 @@ var DEFAULT_SINKS = [
11400
11400
  // pattern with a language-scoped classless entry. The method name
11401
11401
  // `redirect` is rare outside HTTP frameworks so the FP risk is low.
11402
11402
  { method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["javascript", "typescript"] },
11403
+ // Node.js LDAP Injection (ldapjs) — CWE-90
11404
+ // cognium-dev#104 Sprint 22: receiver matches the canonical ldapjs
11405
+ // import name (`const ldap = require('ldapjs')` → ldap.search/...).
11406
+ { method: "search", class: "ldap", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
11407
+ { method: "searchSync", class: "ldap", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
11408
+ { method: "search", class: "ldapjs", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
11409
+ { method: "searchSync", class: "ldapjs", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
11410
+ // Node.js XPath Injection (xpath module) — CWE-643
11411
+ // cognium-dev#104 Sprint 22: `const xpath = require('xpath')` → xpath.select/select1/evaluate.
11412
+ { method: "select", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11413
+ { method: "select1", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11414
+ { method: "evaluate", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11415
+ { method: "parse", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11416
+ // Node.js XXE (libxmljs, xmldom) — CWE-611
11417
+ // cognium-dev#104 Sprint 22: `const libxml = require('libxmljs')` (or 'libxml')
11418
+ // → libxml.parseXml(src, {noent: true}). xmldom DOMParser via parseFromString.
11419
+ { method: "parseXml", class: "libxml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11420
+ { method: "parseXmlString", class: "libxml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11421
+ { method: "parseXml", class: "libxmljs", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11422
+ { method: "parseXmlString", class: "libxmljs", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11423
+ { method: "parseFromString", class: "DOMParser", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11424
+ { method: "parseFromString", class: "xmldom", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11425
+ // Node.js Server-Side Template Injection (SSTI) — CWE-94
11426
+ // cognium-dev#104 Sprint 22: ejs/handlebars/pug template render with
11427
+ // tainted templates → arbitrary JS execution. Uses `code_injection`
11428
+ // SinkType to mirror the Python Jinja2/Mako pattern above.
11429
+ { method: "render", class: "ejs", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11430
+ { method: "compile", class: "ejs", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11431
+ { method: "render", class: "handlebars", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11432
+ { method: "compile", class: "handlebars", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11433
+ { method: "render", class: "pug", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11434
+ { method: "compile", class: "pug", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11435
+ { method: "render", class: "mustache", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11436
+ { method: "render", class: "nunjucks", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11437
+ { method: "renderString", class: "nunjucks", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11403
11438
  // =========================================================================
11404
11439
  // Python Sinks
11405
11440
  // =========================================================================
@@ -11509,6 +11544,16 @@ var DEFAULT_SINKS = [
11509
11544
  { method: "delete_one", class: "Collection", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0] },
11510
11545
  { method: "delete_many", class: "Collection", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0] },
11511
11546
  { method: "aggregate", class: "Collection", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0] },
11547
+ // pymongo dynamic attribute-access pattern: `db.users.find({...})` — receiver
11548
+ // class isn't statically known. Method-only entries restricted to Python.
11549
+ // cognium-dev#104 Sprint 22.
11550
+ { method: "find_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
11551
+ { method: "update_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0, 1], languages: ["python"] },
11552
+ { method: "update_many", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0, 1], languages: ["python"] },
11553
+ { method: "delete_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
11554
+ { method: "delete_many", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
11555
+ { method: "replace_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0, 1], languages: ["python"] },
11556
+ { method: "count_documents", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
11512
11557
  // Python Template Injection (Jinja2, Mako)
11513
11558
  { method: "from_string", class: "Template", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
11514
11559
  { method: "Template", class: "jinja2", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
@@ -11519,6 +11564,15 @@ var DEFAULT_SINKS = [
11519
11564
  { method: "error", class: "logger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11520
11565
  { method: "debug", class: "logger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11521
11566
  { method: "critical", class: "logger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11567
+ // Python `logging` module top-level functions (e.g. logging.info(...))
11568
+ // — cognium-dev#104 Sprint 22: OOP fixtures use `import logging; logging.info(self.msg)`.
11569
+ { method: "info", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11570
+ { method: "warning", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11571
+ { method: "error", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11572
+ { method: "debug", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11573
+ { method: "critical", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11574
+ { method: "log", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [1] },
11575
+ { method: "exception", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11522
11576
  // =========================================================================
11523
11577
  // Java CWE-Bench Enhancement Patterns (Collection/Builder)
11524
11578
  // =========================================================================
@@ -16231,6 +16285,9 @@ function isFalsePositive(result, sinkLine, taintedVar) {
16231
16285
  if (varValue && varValue.type !== "unknown" && !result.tainted.has(taintedVar)) {
16232
16286
  return { isFalsePositive: true, reason: `variable_is_constant: ${varValue.value}` };
16233
16287
  }
16288
+ if (taintedVar.startsWith("self.") || taintedVar.startsWith("this.")) {
16289
+ return { isFalsePositive: false, reason: null };
16290
+ }
16234
16291
  if (result.symbols.has(taintedVar) && !result.tainted.has(taintedVar)) {
16235
16292
  return { isFalsePositive: true, reason: "variable_not_tainted" };
16236
16293
  }
@@ -11334,6 +11334,41 @@ var DEFAULT_SINKS = [
11334
11334
  // pattern with a language-scoped classless entry. The method name
11335
11335
  // `redirect` is rare outside HTTP frameworks so the FP risk is low.
11336
11336
  { method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["javascript", "typescript"] },
11337
+ // Node.js LDAP Injection (ldapjs) — CWE-90
11338
+ // cognium-dev#104 Sprint 22: receiver matches the canonical ldapjs
11339
+ // import name (`const ldap = require('ldapjs')` → ldap.search/...).
11340
+ { method: "search", class: "ldap", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
11341
+ { method: "searchSync", class: "ldap", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
11342
+ { method: "search", class: "ldapjs", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
11343
+ { method: "searchSync", class: "ldapjs", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [1, 2], languages: ["javascript", "typescript"] },
11344
+ // Node.js XPath Injection (xpath module) — CWE-643
11345
+ // cognium-dev#104 Sprint 22: `const xpath = require('xpath')` → xpath.select/select1/evaluate.
11346
+ { method: "select", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11347
+ { method: "select1", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11348
+ { method: "evaluate", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11349
+ { method: "parse", class: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11350
+ // Node.js XXE (libxmljs, xmldom) — CWE-611
11351
+ // cognium-dev#104 Sprint 22: `const libxml = require('libxmljs')` (or 'libxml')
11352
+ // → libxml.parseXml(src, {noent: true}). xmldom DOMParser via parseFromString.
11353
+ { method: "parseXml", class: "libxml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11354
+ { method: "parseXmlString", class: "libxml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11355
+ { method: "parseXml", class: "libxmljs", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11356
+ { method: "parseXmlString", class: "libxmljs", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11357
+ { method: "parseFromString", class: "DOMParser", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11358
+ { method: "parseFromString", class: "xmldom", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
11359
+ // Node.js Server-Side Template Injection (SSTI) — CWE-94
11360
+ // cognium-dev#104 Sprint 22: ejs/handlebars/pug template render with
11361
+ // tainted templates → arbitrary JS execution. Uses `code_injection`
11362
+ // SinkType to mirror the Python Jinja2/Mako pattern above.
11363
+ { method: "render", class: "ejs", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11364
+ { method: "compile", class: "ejs", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11365
+ { method: "render", class: "handlebars", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11366
+ { method: "compile", class: "handlebars", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11367
+ { method: "render", class: "pug", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11368
+ { method: "compile", class: "pug", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11369
+ { method: "render", class: "mustache", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11370
+ { method: "render", class: "nunjucks", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11371
+ { method: "renderString", class: "nunjucks", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
11337
11372
  // =========================================================================
11338
11373
  // Python Sinks
11339
11374
  // =========================================================================
@@ -11443,6 +11478,16 @@ var DEFAULT_SINKS = [
11443
11478
  { method: "delete_one", class: "Collection", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0] },
11444
11479
  { method: "delete_many", class: "Collection", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0] },
11445
11480
  { method: "aggregate", class: "Collection", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0] },
11481
+ // pymongo dynamic attribute-access pattern: `db.users.find({...})` — receiver
11482
+ // class isn't statically known. Method-only entries restricted to Python.
11483
+ // cognium-dev#104 Sprint 22.
11484
+ { method: "find_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
11485
+ { method: "update_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0, 1], languages: ["python"] },
11486
+ { method: "update_many", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0, 1], languages: ["python"] },
11487
+ { method: "delete_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
11488
+ { method: "delete_many", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
11489
+ { method: "replace_one", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0, 1], languages: ["python"] },
11490
+ { method: "count_documents", type: "nosql_injection", cwe: "CWE-943", severity: "critical", arg_positions: [0], languages: ["python"] },
11446
11491
  // Python Template Injection (Jinja2, Mako)
11447
11492
  { method: "from_string", class: "Template", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
11448
11493
  { method: "Template", class: "jinja2", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
@@ -11453,6 +11498,15 @@ var DEFAULT_SINKS = [
11453
11498
  { method: "error", class: "logger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11454
11499
  { method: "debug", class: "logger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11455
11500
  { method: "critical", class: "logger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11501
+ // Python `logging` module top-level functions (e.g. logging.info(...))
11502
+ // — cognium-dev#104 Sprint 22: OOP fixtures use `import logging; logging.info(self.msg)`.
11503
+ { method: "info", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11504
+ { method: "warning", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11505
+ { method: "error", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11506
+ { method: "debug", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11507
+ { method: "critical", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11508
+ { method: "log", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [1] },
11509
+ { method: "exception", class: "logging", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0] },
11456
11510
  // =========================================================================
11457
11511
  // Java CWE-Bench Enhancement Patterns (Collection/Builder)
11458
11512
  // =========================================================================
@@ -16165,6 +16219,9 @@ function isFalsePositive(result, sinkLine, taintedVar) {
16165
16219
  if (varValue && varValue.type !== "unknown" && !result.tainted.has(taintedVar)) {
16166
16220
  return { isFalsePositive: true, reason: `variable_is_constant: ${varValue.value}` };
16167
16221
  }
16222
+ if (taintedVar.startsWith("self.") || taintedVar.startsWith("this.")) {
16223
+ return { isFalsePositive: false, reason: null };
16224
+ }
16168
16225
  if (result.symbols.has(taintedVar) && !result.tainted.has(taintedVar)) {
16169
16226
  return { isFalsePositive: true, reason: "variable_not_tainted" };
16170
16227
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "circle-ir",
3
- "version": "3.71.0",
3
+ "version": "3.72.1",
4
4
  "description": "High-performance Static Application Security Testing (SAST) library for detecting security vulnerabilities through taint analysis",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",