cognium-dev 3.90.0 → 3.91.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.
- package/README.md +27 -0
- package/dist/cli.js +51 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -213,6 +213,33 @@ Found 2 vulnerability(ies) in 1 file(s)
|
|
|
213
213
|
|
|
214
214
|
Use `-v` flag to see all scanned files including clean ones.
|
|
215
215
|
|
|
216
|
+
### Output streams (stdout vs stderr)
|
|
217
|
+
|
|
218
|
+
`cognium-dev` follows the standard CLI convention: machine-readable payload on **stdout**, diagnostics on **stderr**.
|
|
219
|
+
|
|
220
|
+
| Output | Stream | Notes |
|
|
221
|
+
|--------|--------|-------|
|
|
222
|
+
| `--format json` document | **stdout** | Pure JSON starting at character 1. No banner, no preamble. Safe to pipe directly to `jq`, `json_pp`, etc. |
|
|
223
|
+
| `--format sarif` document | **stdout** | Pure SARIF 2.1.0 JSON. Same contract as `--format json`. |
|
|
224
|
+
| `--format text` report | **stdout** | The human-readable report (default). |
|
|
225
|
+
| Status lines (`Loaded config: …`, `Suppressed N finding(s) …`, `Results written to …`) | **stderr** | |
|
|
226
|
+
| Spinner animation and final status (`✔ Scanned N file(s)`) | **stderr** | |
|
|
227
|
+
| Error messages and usage hints | **stderr** | |
|
|
228
|
+
| Library log output (cross-file phase markers, budget warnings, etc.) | **stderr** | Silent by default; enable with `--log-level <level>` or `COGNIUM_LOG_LEVEL`. |
|
|
229
|
+
| Findings instrumentation (`CIRCLE_IR_INSTRUMENT_FINDINGS=1`) | **stderr** | JSONL `[finding] …` / `[findings-summary] …` lines. |
|
|
230
|
+
|
|
231
|
+
The stdout contract for `--format json` and `--format sarif` is **stable**: pure parseable payload, version included inside the JSON object (not as a stdout preamble). Consumers can safely pipe stdout to a parser without skip-the-first-line idioms.
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# Safe — stdout is pure JSON
|
|
235
|
+
cognium-dev scan ./src --format json | jq '.summary'
|
|
236
|
+
|
|
237
|
+
# Status lines and warnings on stderr, JSON on stdout
|
|
238
|
+
cognium-dev scan ./src --format json > results.json 2> scan.log
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
If you previously relied on a `tail -n +2` or `split("\n",1)[1]` idiom against pre-3.89.2 builds, drop it — there is no longer a stdout banner to skip.
|
|
242
|
+
|
|
216
243
|
## Detected Vulnerabilities
|
|
217
244
|
|
|
218
245
|
| Type | CWE | Severity | Description |
|
package/dist/cli.js
CHANGED
|
@@ -15075,8 +15075,17 @@ class AnalysisPipeline {
|
|
|
15075
15075
|
return findings;
|
|
15076
15076
|
}
|
|
15077
15077
|
};
|
|
15078
|
+
const timingEnabled = globalThis.__circleIrPassTiming === true;
|
|
15078
15079
|
for (const pass of this.passes) {
|
|
15080
|
+
if (timingEnabled) {
|
|
15081
|
+
console.error(`[pass-start] ${pass.name} file=${graph.ir.meta.file}`);
|
|
15082
|
+
}
|
|
15083
|
+
const t0 = timingEnabled ? Date.now() : 0;
|
|
15079
15084
|
const result = pass.run(context);
|
|
15085
|
+
if (timingEnabled) {
|
|
15086
|
+
const dt = Date.now() - t0;
|
|
15087
|
+
console.error(`[pass-timing] ${pass.name} ${dt}ms file=${graph.ir.meta.file}`);
|
|
15088
|
+
}
|
|
15080
15089
|
results.set(pass.name, result);
|
|
15081
15090
|
}
|
|
15082
15091
|
return { results, findings };
|
|
@@ -15857,6 +15866,7 @@ class ConstantPropagator {
|
|
|
15857
15866
|
inConstructor = false;
|
|
15858
15867
|
constructorParamPositions = new Map;
|
|
15859
15868
|
safePatternFieldsCache = null;
|
|
15869
|
+
isTaintedExpressionCache = null;
|
|
15860
15870
|
analyze(tree, sourceCode, additionalTaintPatterns = [], sanitizerMethods = [], taintedParameters = []) {
|
|
15861
15871
|
this.source = sourceCode;
|
|
15862
15872
|
this.additionalTaintPatterns = additionalTaintPatterns;
|
|
@@ -15888,6 +15898,7 @@ class ConstantPropagator {
|
|
|
15888
15898
|
this.inConstructor = false;
|
|
15889
15899
|
this.constructorParamPositions.clear();
|
|
15890
15900
|
this.safePatternFieldsCache = null;
|
|
15901
|
+
this.isTaintedExpressionCache = null;
|
|
15891
15902
|
this.collectClassFields(tree.rootNode);
|
|
15892
15903
|
for (const methodName of sanitizerMethods) {
|
|
15893
15904
|
this.methodReturnsSanitized.add(methodName);
|
|
@@ -17237,18 +17248,52 @@ class ConstantPropagator {
|
|
|
17237
17248
|
return null;
|
|
17238
17249
|
}
|
|
17239
17250
|
isTaintedExpression(node) {
|
|
17251
|
+
const isTopLevel = this.isTaintedExpressionCache === null;
|
|
17252
|
+
if (isTopLevel) {
|
|
17253
|
+
this.isTaintedExpressionCache = new Map;
|
|
17254
|
+
}
|
|
17255
|
+
try {
|
|
17256
|
+
return this.isTaintedExpressionImpl(node);
|
|
17257
|
+
} finally {
|
|
17258
|
+
if (isTopLevel) {
|
|
17259
|
+
this.isTaintedExpressionCache = null;
|
|
17260
|
+
}
|
|
17261
|
+
}
|
|
17262
|
+
}
|
|
17263
|
+
isTaintedExpressionImpl(node) {
|
|
17264
|
+
const cache = this.isTaintedExpressionCache;
|
|
17265
|
+
const rootId = node.id;
|
|
17266
|
+
const cachedRoot = cache.get(rootId);
|
|
17267
|
+
if (cachedRoot !== undefined) {
|
|
17268
|
+
return cachedRoot;
|
|
17269
|
+
}
|
|
17240
17270
|
const stack = [node];
|
|
17241
17271
|
while (stack.length > 0) {
|
|
17242
17272
|
const current = stack.pop();
|
|
17273
|
+
const currentId = current.id;
|
|
17274
|
+
const cached = cache.get(currentId);
|
|
17275
|
+
if (cached !== undefined) {
|
|
17276
|
+
if (cached) {
|
|
17277
|
+
cache.set(rootId, true);
|
|
17278
|
+
return true;
|
|
17279
|
+
}
|
|
17280
|
+
continue;
|
|
17281
|
+
}
|
|
17243
17282
|
const result = this.isTaintedExpressionStep(current);
|
|
17244
|
-
if (result === true)
|
|
17283
|
+
if (result === true) {
|
|
17284
|
+
cache.set(currentId, true);
|
|
17285
|
+
cache.set(rootId, true);
|
|
17245
17286
|
return true;
|
|
17246
|
-
|
|
17287
|
+
}
|
|
17288
|
+
if (result === false) {
|
|
17289
|
+
cache.set(currentId, false);
|
|
17247
17290
|
continue;
|
|
17291
|
+
}
|
|
17248
17292
|
for (let i2 = current.children.length - 1;i2 >= 0; i2--) {
|
|
17249
17293
|
stack.push(current.children[i2]);
|
|
17250
17294
|
}
|
|
17251
17295
|
}
|
|
17296
|
+
cache.set(rootId, false);
|
|
17252
17297
|
return false;
|
|
17253
17298
|
}
|
|
17254
17299
|
isTaintedExpressionStep(node) {
|
|
@@ -24956,6 +25001,9 @@ var TIER_1_METHOD_ANNOTATIONS = new Set([
|
|
|
24956
25001
|
var TIER_1_CLASS_ANNOTATIONS = new Set([
|
|
24957
25002
|
"RestController",
|
|
24958
25003
|
"Controller",
|
|
25004
|
+
"Service",
|
|
25005
|
+
"Repository",
|
|
25006
|
+
"Component",
|
|
24959
25007
|
"Path",
|
|
24960
25008
|
"WebServlet",
|
|
24961
25009
|
"ServerEndpoint",
|
|
@@ -34472,7 +34520,7 @@ var colors = {
|
|
|
34472
34520
|
};
|
|
34473
34521
|
|
|
34474
34522
|
// src/version.ts
|
|
34475
|
-
var version = "3.
|
|
34523
|
+
var version = "3.91.0";
|
|
34476
34524
|
|
|
34477
34525
|
// src/formatters.ts
|
|
34478
34526
|
var SINK_SEVERITY = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.91.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.
|
|
68
|
+
"circle-ir": "^3.91.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.5.0",
|