cognium-dev 4.0.0 → 4.2.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 (3) hide show
  1. package/README.md +7 -1
  2. package/dist/cli.js +34 -12
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -65,7 +65,7 @@ Scan files or directories for security vulnerabilities.
65
65
  cognium-dev scan <path> [options]
66
66
 
67
67
  Options:
68
- -l, --language <lang> Force language (java|javascript|typescript|python|go|rust|bash|html)
68
+ -l, --language <lang> Force language (java|javascript|typescript|python|go|rust|bash|html|csharp)
69
69
  -f, --format <format> Output format (text|json|sarif) [default: text]
70
70
  --threads <n> Parallel analysis threads [default: 4]
71
71
  --severity <level> Filter by severity:
@@ -307,6 +307,12 @@ Filter to security findings only: `cognium-dev scan ./src --category security`
307
307
  | Rust | `.rs` | Actix-web, Rocket, Axum |
308
308
  | Bash | `.sh`, `.bash` | Shell scripts |
309
309
  | HTML | `.html`, `.htm` | Web extraction preprocessor |
310
+ | C#/.NET _(experimental)_ | `.cs` | ASP.NET Core, ADO.NET, EF Core |
311
+
312
+ > **C#/.NET is experimental / preview** (since 4.0.0). Straight-line taint
313
+ > analysis across 10 CWE families (SQLi, command injection, path traversal,
314
+ > SSRF, code injection, XSS, deserialization, LDAP, XPath, XXE). Not yet
315
+ > benchmark-verified — expect gaps in branch/alias precision and detector breadth.
310
316
 
311
317
  ## Configuration
312
318
 
package/dist/cli.js CHANGED
@@ -14877,19 +14877,19 @@ function walkBackwardDefs(startDefId, chainsByToDef, defById, options = {}) {
14877
14877
  // ../circle-ir/dist/analysis/findings.js
14878
14878
  function canSourceReachSink(sourceType, sinkType) {
14879
14879
  const sourceToSinkMapping = {
14880
- http_param: ["sql_injection", "command_injection", "path_traversal", "xss", "xpath_injection", "ldap_injection", "ssrf", "mybatis_mapper_call", "code_injection", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "deserialization", "log_injection", "format_string", "nosql_injection"],
14881
- http_body: ["sql_injection", "command_injection", "deserialization", "xxe", "xss", "code_injection", "mybatis_mapper_call", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection"],
14882
- http_header: ["sql_injection", "xss", "ssrf", "mybatis_mapper_call", "code_injection", "crlf", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection"],
14883
- http_cookie: ["sql_injection", "xss", "mybatis_mapper_call", "code_injection", "crlf", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection"],
14884
- http_path: ["path_traversal", "sql_injection", "ssrf", "mybatis_mapper_call", "open_redirect", "trust_boundary", "xss", "log_injection", "format_string"],
14885
- http_query: ["sql_injection", "command_injection", "xss", "ssrf", "mybatis_mapper_call", "code_injection", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "deserialization", "log_injection", "format_string", "nosql_injection"],
14886
- io_input: ["command_injection", "path_traversal", "deserialization", "xxe", "code_injection", "xss", "ssrf", "log_injection", "format_string"],
14880
+ http_param: ["sql_injection", "command_injection", "path_traversal", "xss", "xpath_injection", "ldap_injection", "ssrf", "mybatis_mapper_call", "code_injection", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "deserialization", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
14881
+ http_body: ["sql_injection", "command_injection", "deserialization", "xxe", "xss", "code_injection", "mybatis_mapper_call", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
14882
+ http_header: ["sql_injection", "xss", "ssrf", "mybatis_mapper_call", "code_injection", "crlf", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
14883
+ http_cookie: ["sql_injection", "xss", "mybatis_mapper_call", "code_injection", "crlf", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
14884
+ http_path: ["path_traversal", "sql_injection", "ssrf", "mybatis_mapper_call", "open_redirect", "trust_boundary", "xss", "log_injection", "format_string", "prompt_injection"],
14885
+ http_query: ["sql_injection", "command_injection", "xss", "ssrf", "mybatis_mapper_call", "code_injection", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "deserialization", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
14886
+ io_input: ["command_injection", "path_traversal", "deserialization", "xxe", "code_injection", "xss", "ssrf", "log_injection", "format_string", "prompt_injection"],
14887
14887
  env_input: ["command_injection", "path_traversal"],
14888
14888
  db_input: ["xss", "sql_injection", "log_injection"],
14889
14889
  file_input: ["deserialization", "xxe", "path_traversal", "command_injection", "code_injection"],
14890
- network_input: ["sql_injection", "command_injection", "xss", "ssrf", "log_injection", "format_string", "nosql_injection"],
14890
+ network_input: ["sql_injection", "command_injection", "xss", "ssrf", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
14891
14891
  config_param: ["sql_injection", "command_injection", "path_traversal", "xss", "ssrf", "log_injection", "format_string"],
14892
- interprocedural_param: ["sql_injection", "command_injection", "path_traversal", "xss", "xpath_injection", "ldap_injection", "ssrf", "code_injection", "mybatis_mapper_call", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection"],
14892
+ interprocedural_param: ["sql_injection", "command_injection", "path_traversal", "xss", "xpath_injection", "ldap_injection", "ssrf", "code_injection", "mybatis_mapper_call", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
14893
14893
  plugin_param: ["sql_injection", "command_injection", "path_traversal", "xss", "code_injection", "log_injection", "format_string"]
14894
14894
  };
14895
14895
  const validSinks = sourceToSinkMapping[sourceType];
@@ -20022,6 +20022,10 @@ function applyLibraryApiSurfaceDowngrade(findings) {
20022
20022
  }
20023
20023
 
20024
20024
  // ../circle-ir/dist/analysis/note-coalescer.js
20025
+ var CLICKJACKING_PAIR = new Set(["missing-x-frame-options", "missing-csp-frame-ancestors"]);
20026
+ function levelRank(level) {
20027
+ return level === "error" ? 0 : level === "warning" ? 1 : 2;
20028
+ }
20025
20029
  function coalesceNoteLevelFindings(findings) {
20026
20030
  if (findings.length < 2)
20027
20031
  return [...findings];
@@ -20039,11 +20043,27 @@ function coalesceNoteLevelFindings(findings) {
20039
20043
  }
20040
20044
  const out2 = [];
20041
20045
  for (const key of order) {
20042
- const bucket = groups.get(key);
20046
+ let bucket = groups.get(key);
20043
20047
  if (bucket.length === 1) {
20044
20048
  out2.push(bucket[0]);
20045
20049
  continue;
20046
20050
  }
20051
+ const cj = bucket.filter((f) => CLICKJACKING_PAIR.has(f.rule_id));
20052
+ if (new Set(cj.map((f) => f.rule_id)).size === CLICKJACKING_PAIR.size) {
20053
+ const primary2 = [...cj].sort((a, b) => levelRank(a.level) - levelRank(b.level) || a.rule_id.localeCompare(b.rule_id))[0];
20054
+ const labels = Array.from(new Set([
20055
+ ...primary2.labels ?? [],
20056
+ ...cj.flatMap((f) => [f.rule_id, ...f.labels ?? []])
20057
+ ])).filter((l) => l !== primary2.rule_id);
20058
+ out2.push({ ...primary2, labels });
20059
+ bucket = bucket.filter((f) => !CLICKJACKING_PAIR.has(f.rule_id));
20060
+ if (bucket.length === 0)
20061
+ continue;
20062
+ if (bucket.length === 1) {
20063
+ out2.push(bucket[0]);
20064
+ continue;
20065
+ }
20066
+ }
20047
20067
  const allNote = bucket.every((f) => f.level === "note");
20048
20068
  if (!allNote) {
20049
20069
  for (const f of bucket)
@@ -25596,6 +25616,8 @@ function findJavaScriptAssignmentSources(sourceCode, language) {
25596
25616
  const sources = [];
25597
25617
  const lines = sourceCode.split(`
25598
25618
  `);
25619
+ const isRouteHandler = /export\s+(?:async\s+)?(?:function\s+(?:GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS|loader|action)\b|const\s+(?:GET|POST|PUT|PATCH|DELETE|loader|action)\b)/.test(sourceCode) && /\{[^}]*\bparams\b[^}]*\}/.test(sourceCode);
25620
+ const patterns = isRouteHandler ? [...JS_TAINTED_PATTERNS, { pattern: /\bparams\s*[.[]/, type: "http_path" }] : JS_TAINTED_PATTERNS;
25599
25621
  for (let lineNum = 0;lineNum < lines.length; lineNum++) {
25600
25622
  const line = lines[lineNum];
25601
25623
  const lineNumber = lineNum + 1;
@@ -25603,7 +25625,7 @@ function findJavaScriptAssignmentSources(sourceCode, language) {
25603
25625
  if (!assignmentMatch)
25604
25626
  continue;
25605
25627
  const [, varName, rhs] = assignmentMatch;
25606
- for (const { pattern, type } of JS_TAINTED_PATTERNS) {
25628
+ for (const { pattern, type } of patterns) {
25607
25629
  if (pattern.test(rhs)) {
25608
25630
  const alreadyExists = sources.some((s) => s.line === lineNumber && s.type === type);
25609
25631
  if (!alreadyExists) {
@@ -47756,7 +47778,7 @@ var colors = {
47756
47778
  };
47757
47779
 
47758
47780
  // src/version.ts
47759
- var version = "4.0.0";
47781
+ var version = "4.2.0";
47760
47782
 
47761
47783
  // src/formatters.ts
47762
47784
  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": "4.0.0",
3
+ "version": "4.2.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": "^4.0.0"
69
+ "circle-ir": "^4.2.0"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/node": "^25.5.0",