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.
- package/dist/analysis/config-loader.d.ts.map +1 -1
- package/dist/analysis/config-loader.js +54 -0
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/constant-propagation/index.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/index.js +14 -0
- package/dist/analysis/constant-propagation/index.js.map +1 -1
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +62 -21
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.js +19 -0
- package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
- package/dist/browser/circle-ir.js +110 -19
- package/dist/core/circle-ir-core.cjs +57 -0
- package/dist/core/circle-ir-core.js +57 -0
- package/package.json +1 -1
|
@@ -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
|
|
22536
|
-
|
|
22537
|
-
|
|
22538
|
-
|
|
22539
|
-
|
|
22540
|
-
|
|
22541
|
-
|
|
22542
|
-
|
|
22543
|
-
|
|
22544
|
-
}
|
|
22545
|
-
|
|
22546
|
-
|
|
22547
|
-
|
|
22548
|
-
|
|
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
|
-
|
|
22553
|
-
|
|
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.
|
|
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",
|