@vyuhlabs/dxkit 2.4.7 → 2.5.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/CHANGELOG.md +456 -30
- package/README.md +360 -439
- package/dist/analyzers/bom/gather.d.ts +3 -3
- package/dist/analyzers/bom/gather.js +3 -3
- package/dist/analyzers/bom/index.js +2 -2
- package/dist/analyzers/bom/index.js.map +1 -1
- package/dist/analyzers/dashboard/index.d.ts.map +1 -1
- package/dist/analyzers/dashboard/index.js +4 -3
- package/dist/analyzers/dashboard/index.js.map +1 -1
- package/dist/analyzers/developer/index.d.ts.map +1 -1
- package/dist/analyzers/developer/index.js +2 -1
- package/dist/analyzers/developer/index.js.map +1 -1
- package/dist/analyzers/dispatcher.d.ts +15 -0
- package/dist/analyzers/dispatcher.d.ts.map +1 -1
- package/dist/analyzers/dispatcher.js +42 -6
- package/dist/analyzers/dispatcher.js.map +1 -1
- package/dist/analyzers/health.d.ts.map +1 -1
- package/dist/analyzers/health.js +11 -1
- package/dist/analyzers/health.js.map +1 -1
- package/dist/analyzers/licenses/gather.d.ts +1 -1
- package/dist/analyzers/licenses/gather.d.ts.map +1 -1
- package/dist/analyzers/licenses/gather.js +18 -2
- package/dist/analyzers/licenses/gather.js.map +1 -1
- package/dist/analyzers/quality/index.d.ts.map +1 -1
- package/dist/analyzers/quality/index.js +10 -2
- package/dist/analyzers/quality/index.js.map +1 -1
- package/dist/analyzers/security/aggregator.d.ts.map +1 -1
- package/dist/analyzers/security/aggregator.js +8 -48
- package/dist/analyzers/security/aggregator.js.map +1 -1
- package/dist/analyzers/security/gather.d.ts +4 -3
- package/dist/analyzers/security/gather.d.ts.map +1 -1
- package/dist/analyzers/security/gather.js +23 -5
- package/dist/analyzers/security/gather.js.map +1 -1
- package/dist/analyzers/security/index.d.ts +1 -1
- package/dist/analyzers/security/index.js +2 -2
- package/dist/analyzers/security/index.js.map +1 -1
- package/dist/analyzers/tools/autogen-header.js +1 -1
- package/dist/analyzers/tools/cloc.js +3 -3
- package/dist/analyzers/tools/cloc.js.map +1 -1
- package/dist/analyzers/tools/deadline.d.ts +67 -0
- package/dist/analyzers/tools/deadline.d.ts.map +1 -0
- package/dist/analyzers/tools/deadline.js +81 -0
- package/dist/analyzers/tools/deadline.js.map +1 -0
- package/dist/analyzers/tools/exclusions.d.ts +6 -6
- package/dist/analyzers/tools/exclusions.js +6 -6
- package/dist/analyzers/tools/fingerprint.d.ts +91 -26
- package/dist/analyzers/tools/fingerprint.d.ts.map +1 -1
- package/dist/analyzers/tools/fingerprint.js +111 -22
- package/dist/analyzers/tools/fingerprint.js.map +1 -1
- package/dist/analyzers/tools/generic.d.ts.map +1 -1
- package/dist/analyzers/tools/generic.js +7 -2
- package/dist/analyzers/tools/generic.js.map +1 -1
- package/dist/analyzers/tools/gitleaks.d.ts +24 -1
- package/dist/analyzers/tools/gitleaks.d.ts.map +1 -1
- package/dist/analyzers/tools/gitleaks.js +21 -12
- package/dist/analyzers/tools/gitleaks.js.map +1 -1
- package/dist/analyzers/tools/graphify.js +1 -1
- package/dist/analyzers/tools/jscpd.js +1 -1
- package/dist/analyzers/tools/jscpd.js.map +1 -1
- package/dist/analyzers/tools/lint-label.d.ts +29 -0
- package/dist/analyzers/tools/lint-label.d.ts.map +1 -0
- package/dist/analyzers/tools/lint-label.js +23 -0
- package/dist/analyzers/tools/lint-label.js.map +1 -0
- package/dist/analyzers/tools/nuget-package-reference.d.ts +6 -4
- package/dist/analyzers/tools/nuget-package-reference.d.ts.map +1 -1
- package/dist/analyzers/tools/nuget-package-reference.js +7 -5
- package/dist/analyzers/tools/nuget-package-reference.js.map +1 -1
- package/dist/analyzers/tools/report-date.d.ts +17 -0
- package/dist/analyzers/tools/report-date.d.ts.map +1 -0
- package/dist/analyzers/tools/report-date.js +26 -0
- package/dist/analyzers/tools/report-date.js.map +1 -0
- package/dist/analyzers/tools/runner.js +3 -3
- package/dist/analyzers/tools/runner.js.map +1 -1
- package/dist/analyzers/tools/vendored-advisor.js +1 -1
- package/dist/analyzers/tools/walk-paths.d.ts +1 -1
- package/dist/analyzers/tools/walk-paths.js +1 -1
- package/dist/analyzers/tools/walk-source-files.js +1 -1
- package/dist/analyzers/types.d.ts +6 -4
- package/dist/analyzers/types.d.ts.map +1 -1
- package/dist/baseline/baseline-file.d.ts +104 -0
- package/dist/baseline/baseline-file.d.ts.map +1 -0
- package/dist/baseline/baseline-file.js +110 -0
- package/dist/baseline/baseline-file.js.map +1 -0
- package/dist/baseline/check-renderers.d.ts +108 -0
- package/dist/baseline/check-renderers.d.ts.map +1 -0
- package/dist/baseline/check-renderers.js +379 -0
- package/dist/baseline/check-renderers.js.map +1 -0
- package/dist/baseline/check.d.ts +127 -0
- package/dist/baseline/check.d.ts.map +1 -0
- package/dist/baseline/check.js +462 -0
- package/dist/baseline/check.js.map +1 -0
- package/dist/baseline/content-hash.d.ts +83 -0
- package/dist/baseline/content-hash.d.ts.map +1 -0
- package/dist/baseline/content-hash.js +131 -0
- package/dist/baseline/content-hash.js.map +1 -0
- package/dist/baseline/create.d.ts +96 -0
- package/dist/baseline/create.d.ts.map +1 -0
- package/dist/baseline/create.js +339 -0
- package/dist/baseline/create.js.map +1 -0
- package/dist/baseline/entry-to-located.d.ts +35 -0
- package/dist/baseline/entry-to-located.d.ts.map +1 -0
- package/dist/baseline/entry-to-located.js +72 -0
- package/dist/baseline/entry-to-located.js.map +1 -0
- package/dist/baseline/finding-identity.d.ts +47 -0
- package/dist/baseline/finding-identity.d.ts.map +1 -0
- package/dist/baseline/finding-identity.js +292 -0
- package/dist/baseline/finding-identity.js.map +1 -0
- package/dist/baseline/git-aware-match.d.ts +146 -0
- package/dist/baseline/git-aware-match.d.ts.map +1 -0
- package/dist/baseline/git-aware-match.js +439 -0
- package/dist/baseline/git-aware-match.js.map +1 -0
- package/dist/baseline/policy.d.ts +171 -0
- package/dist/baseline/policy.d.ts.map +1 -0
- package/dist/baseline/policy.js +206 -0
- package/dist/baseline/policy.js.map +1 -0
- package/dist/baseline/producers/health.d.ts +30 -0
- package/dist/baseline/producers/health.d.ts.map +1 -0
- package/dist/baseline/producers/health.js +42 -0
- package/dist/baseline/producers/health.js.map +1 -0
- package/dist/baseline/producers/index.d.ts +164 -0
- package/dist/baseline/producers/index.d.ts.map +1 -0
- package/dist/baseline/producers/index.js +200 -0
- package/dist/baseline/producers/index.js.map +1 -0
- package/dist/baseline/producers/licenses.d.ts +23 -0
- package/dist/baseline/producers/licenses.d.ts.map +1 -0
- package/dist/baseline/producers/licenses.js +46 -0
- package/dist/baseline/producers/licenses.js.map +1 -0
- package/dist/baseline/producers/quality.d.ts +39 -0
- package/dist/baseline/producers/quality.d.ts.map +1 -0
- package/dist/baseline/producers/quality.js +84 -0
- package/dist/baseline/producers/quality.js.map +1 -0
- package/dist/baseline/producers/secret-hmac.d.ts +45 -0
- package/dist/baseline/producers/secret-hmac.d.ts.map +1 -0
- package/dist/baseline/producers/secret-hmac.js +70 -0
- package/dist/baseline/producers/secret-hmac.js.map +1 -0
- package/dist/baseline/producers/security.d.ts +59 -0
- package/dist/baseline/producers/security.d.ts.map +1 -0
- package/dist/baseline/producers/security.js +135 -0
- package/dist/baseline/producers/security.js.map +1 -0
- package/dist/baseline/producers/tests.d.ts +36 -0
- package/dist/baseline/producers/tests.d.ts.map +1 -0
- package/dist/baseline/producers/tests.js +69 -0
- package/dist/baseline/producers/tests.js.map +1 -0
- package/dist/baseline/salt.d.ts +45 -0
- package/dist/baseline/salt.d.ts.map +1 -0
- package/dist/baseline/salt.js +113 -0
- package/dist/baseline/salt.js.map +1 -0
- package/dist/baseline/show.d.ts +79 -0
- package/dist/baseline/show.d.ts.map +1 -0
- package/dist/baseline/show.js +233 -0
- package/dist/baseline/show.js.map +1 -0
- package/dist/baseline/types.d.ts +482 -0
- package/dist/baseline/types.d.ts.map +1 -0
- package/dist/baseline/types.js +53 -0
- package/dist/baseline/types.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +395 -92
- package/dist/cli.js.map +1 -1
- package/dist/codebase-scanner.d.ts.map +1 -1
- package/dist/codebase-scanner.js +0 -1
- package/dist/codebase-scanner.js.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -4
- package/dist/constants.js.map +1 -1
- package/dist/detect.js +3 -3
- package/dist/detect.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +22 -25
- package/dist/doctor.js.map +1 -1
- package/dist/fail-on.d.ts +84 -0
- package/dist/fail-on.d.ts.map +1 -0
- package/dist/fail-on.js +128 -0
- package/dist/fail-on.js.map +1 -0
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +2 -141
- package/dist/generator.js.map +1 -1
- package/dist/languages/capabilities/provider.d.ts +4 -4
- package/dist/languages/capabilities/types.d.ts +1 -1
- package/dist/languages/csharp.d.ts.map +1 -1
- package/dist/languages/csharp.js +15 -24
- package/dist/languages/csharp.js.map +1 -1
- package/dist/languages/go.d.ts.map +1 -1
- package/dist/languages/go.js +0 -15
- package/dist/languages/go.js.map +1 -1
- package/dist/languages/index.d.ts +4 -3
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js +3 -2
- package/dist/languages/index.js.map +1 -1
- package/dist/languages/java.d.ts.map +1 -1
- package/dist/languages/java.js +0 -6
- package/dist/languages/java.js.map +1 -1
- package/dist/languages/kotlin.d.ts.map +1 -1
- package/dist/languages/kotlin.js +0 -11
- package/dist/languages/kotlin.js.map +1 -1
- package/dist/languages/python.d.ts.map +1 -1
- package/dist/languages/python.js +0 -15
- package/dist/languages/python.js.map +1 -1
- package/dist/languages/ruby.d.ts.map +1 -1
- package/dist/languages/ruby.js +0 -6
- package/dist/languages/ruby.js.map +1 -1
- package/dist/languages/rust.d.ts.map +1 -1
- package/dist/languages/rust.js +0 -4
- package/dist/languages/rust.js.map +1 -1
- package/dist/languages/types.d.ts +9 -35
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript.d.ts.map +1 -1
- package/dist/languages/typescript.js +26 -4
- package/dist/languages/typescript.js.map +1 -1
- package/dist/lib.d.ts +2 -3
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +3 -6
- package/dist/lib.js.map +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +0 -10
- package/dist/prompts.js.map +1 -1
- package/dist/report-schema.d.ts +42 -0
- package/dist/report-schema.d.ts.map +1 -0
- package/dist/report-schema.js +54 -0
- package/dist/report-schema.js.map +1 -0
- package/dist/ship-installers.d.ts +106 -0
- package/dist/ship-installers.d.ts.map +1 -0
- package/dist/ship-installers.js +415 -0
- package/dist/ship-installers.js.map +1 -0
- package/dist/types.d.ts +0 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +0 -4
- package/dist/update.js.map +1 -1
- package/package.json +17 -11
- package/templates/.claude/agents/onboarding.md +5 -4
- package/templates/.claude/agents-available/codebase-explorer.md +1 -1
- package/templates/.claude/agents-available/debugger.md +2 -2
- package/templates/.claude/agents-available/health-auditor.md +2 -2
- package/templates/.claude/commands/doctor.md +20 -12
- package/templates/.claude/skills/build/SKILL.md.template +22 -30
- package/templates/.claude/skills/deploy/SKILL.md.template +5 -25
- package/templates/.claude/skills/doctor/SKILL.md +24 -47
- package/templates/.claude/skills/gcloud/SKILL.md +5 -5
- package/templates/.claude/skills/learned/SKILL.md +1 -1
- package/templates/.claude/skills/pulumi/SKILL.md +2 -2
- package/templates/.claude/skills/quality/SKILL.md.template +4 -23
- package/templates/.claude/skills/review/SKILL.md.template +4 -3
- package/templates/.claude/skills/scaffold/SKILL.md.template +5 -15
- package/templates/.claude/skills/secrets/SKILL.md +20 -21
- package/templates/.claude/skills/session/SKILL.md +20 -31
- package/templates/.claude/skills/test/SKILL.md.template +1 -7
- package/templates/.devcontainer/devcontainer.json +81 -0
- package/templates/.devcontainer/install-agent-clis.sh +42 -0
- package/templates/.devcontainer/post-create.sh +67 -0
- package/templates/.githooks/pre-commit +55 -0
- package/templates/.githooks/pre-push +63 -0
- package/templates/.github/workflows/dxkit-baseline-refresh.yml +78 -0
- package/templates/.github/workflows/dxkit-guardrails.yml +98 -0
- package/templates/CLAUDE.md.template +62 -196
- package/dist/project-yaml.d.ts +0 -13
- package/dist/project-yaml.d.ts.map +0 -1
- package/dist/project-yaml.js +0 -188
- package/dist/project-yaml.js.map +0 -1
- package/templates/.ai/README.md +0 -117
- package/templates/.ai/prompts/execution-prompt.md +0 -9
- package/templates/.ai/prompts/planning-prompt.md +0 -18
- package/templates/.ai/prompts/session-end-template.md +0 -182
- package/templates/.ai/prompts/session-end.md +0 -132
- package/templates/.ai/prompts/session-start.md +0 -109
- package/templates/.ai/prompts/step-by-step.md +0 -113
- package/templates/.ai/sessions/.gitkeep +0 -0
- package/templates/.claude/commands/setup-pr-review.md +0 -72
- package/templates/.devcontainer/Dockerfile.dev.template +0 -89
- package/templates/.devcontainer/devcontainer.json.template +0 -184
- package/templates/.devcontainer/docker-compose.yml.template +0 -105
- package/templates/.devcontainer/init-scripts/01-init.sql.template +0 -12
- package/templates/.devcontainer/post-create.sh.template +0 -298
- package/templates/.github/workflows/ci.yml.template +0 -399
- package/templates/.github/workflows/quality.yml.template +0 -376
- package/templates/.pre-commit-config.yaml.template +0 -106
- package/templates/.project/config/edit_config.py +0 -275
- package/templates/.project/config/project_config.py +0 -894
- package/templates/.project/scripts/codegen/generate-all.sh +0 -20
- package/templates/.project/scripts/codegen/validate-all.sh +0 -17
- package/templates/.project/scripts/docs/generate-all.sh +0 -30
- package/templates/.project/scripts/docs/serve.sh +0 -20
- package/templates/.project/scripts/quality/fix-all.sh +0 -138
- package/templates/.project/scripts/quality/lint-go.sh +0 -34
- package/templates/.project/scripts/quality/lint-python.sh +0 -54
- package/templates/.project/scripts/quality/run-all.sh +0 -497
- package/templates/.project/scripts/session/commit.sh +0 -70
- package/templates/.project/scripts/session/create-pr.sh +0 -165
- package/templates/.project/scripts/session/end.sh +0 -207
- package/templates/.project/scripts/session/start.sh +0 -233
- package/templates/.project/scripts/setup/doctor.sh +0 -404
- package/templates/.project/scripts/setup/interactive-setup.sh +0 -585
- package/templates/.project/scripts/sync/sync-template.sh +0 -328
- package/templates/.project/scripts/test/run-all.sh +0 -179
- package/templates/.project/scripts/test/run-quick.sh +0 -25
- package/templates/Makefile +0 -514
- package/templates/config/versions.yaml +0 -57
- package/templates/configs/go/.golangci.yml.template +0 -172
- package/templates/configs/go/go.mod.template +0 -15
- package/templates/configs/java/README.md +0 -6
- package/templates/configs/kotlin/README.md +0 -6
- package/templates/configs/node/package.json.template +0 -67
- package/templates/configs/node/tsconfig.json.template +0 -53
- package/templates/configs/python/pyproject.toml.template +0 -92
- package/templates/configs/python/pytest.ini.template +0 -64
- package/templates/configs/python/ruff.toml.template +0 -79
- package/templates/configs/ruby/README.md +0 -6
- package/templates/configs/rust/Cargo.toml.template +0 -51
- package/templates/configs/shared/.editorconfig +0 -67
- package/templates/scripts/validate-templates.sh +0 -449
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Race a Promise against a deadline. The wrapper always settles within
|
|
3
|
+
* `deadlineMs + epsilon`, whether the inner Promise resolves, rejects,
|
|
4
|
+
* or never settles at all. Rejection of the inner Promise propagates
|
|
5
|
+
* untouched so callers can still see real provider errors.
|
|
6
|
+
*
|
|
7
|
+
* Why this exists: capability providers shell out to external tools
|
|
8
|
+
* (semgrep, jscpd, graphify, npm audit, pip-audit, …) and occasionally
|
|
9
|
+
* produce a Promise that never settles — typically because the
|
|
10
|
+
* provider awaits multiple async operations in turn and one of them
|
|
11
|
+
* (a `Promise.all`, a non-`runDetached` subprocess, a network call)
|
|
12
|
+
* silently hangs. `runDetached` has its own safety-deadline that
|
|
13
|
+
* forces its Promise to resolve, but providers can produce abandoned
|
|
14
|
+
* Promises outside `runDetached` too. The dispatcher used to wrap
|
|
15
|
+
* those calls in `Promise.allSettled`, which only collapses settled
|
|
16
|
+
* Promises — an unsettled Promise inside leaves the whole capability
|
|
17
|
+
* gather pending forever, the Node event loop empties, and the
|
|
18
|
+
* subprocess exits cleanly with no work done — a silent rc=0 with
|
|
19
|
+
* no report on disk. The reproducible offender on at least one
|
|
20
|
+
* heavy JS-stack customer audit has been `license-checker` walking
|
|
21
|
+
* a deep `node_modules` tree, which occasionally produces an
|
|
22
|
+
* unsettling Promise under concurrent subprocess load.
|
|
23
|
+
*
|
|
24
|
+
* The dispatcher applies this helper per-provider so any single
|
|
25
|
+
* provider that stalls is bounded; the rest of the Promise.allSettled
|
|
26
|
+
* still completes; the stalled source ends up in
|
|
27
|
+
* `DispatchOutcome.skipped` with a deadline reason that surfaces
|
|
28
|
+
* downstream in `toolsUnavailable`. Two non-dispatcher gathers
|
|
29
|
+
* (`gatherDepVulnsWithAvailability`, `gatherLicensesWithAvailability`)
|
|
30
|
+
* iterate packs themselves; they apply the same pattern at their
|
|
31
|
+
* own iteration site.
|
|
32
|
+
*/
|
|
33
|
+
export type DeadlineOutcome<T> = {
|
|
34
|
+
stalled: false;
|
|
35
|
+
value: T;
|
|
36
|
+
} | {
|
|
37
|
+
stalled: true;
|
|
38
|
+
stalledMs: number;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Race `promise` against a `deadlineMs` timer. Returns:
|
|
42
|
+
* - `{ stalled: false, value }` if the Promise resolves before the deadline
|
|
43
|
+
* - `{ stalled: true, stalledMs }` if the deadline fires first
|
|
44
|
+
*
|
|
45
|
+
* Rejections of the inner Promise propagate as rejections of the
|
|
46
|
+
* returned Promise — callers handle them separately (e.g. via
|
|
47
|
+
* `Promise.allSettled`). The internal timer is cleared on settle so a
|
|
48
|
+
* resolved Promise doesn't leave a stray pending timer keeping Node
|
|
49
|
+
* alive past process exit.
|
|
50
|
+
*/
|
|
51
|
+
export declare function withDeadline<T>(promise: Promise<T>, deadlineMs: number): Promise<DeadlineOutcome<T>>;
|
|
52
|
+
/**
|
|
53
|
+
* Default per-provider deadline for capability gathers. Chosen so the
|
|
54
|
+
* deadline only fires on genuine abandoned-Promise hangs, not on slow
|
|
55
|
+
* legitimate tool runs:
|
|
56
|
+
* - jscpd's `runDetached` timeout is 600s; its safety-deadline adds 30s
|
|
57
|
+
* - semgrep's `runDetached` timeout is 300s
|
|
58
|
+
* - depVulns providers (npm/pip/gem audit, govulncheck, cargo-audit,
|
|
59
|
+
* dotnet) typically settle within 60–180s on large monorepos
|
|
60
|
+
*
|
|
61
|
+
* 720s (12 min) sits above the slowest legitimate provider by ~90s of
|
|
62
|
+
* slack for parsing + aggregation. Real provider runs on the customer
|
|
63
|
+
* benchmark repos finish well inside this; only the stuck case trips
|
|
64
|
+
* it.
|
|
65
|
+
*/
|
|
66
|
+
export declare const DEFAULT_PROVIDER_DEADLINE_MS = 720000;
|
|
67
|
+
//# sourceMappingURL=deadline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deadline.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/deadline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,MAAM,eAAe,CAAC,CAAC,IACzB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC5B;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAkB7B;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B,SAAU,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Race a Promise against a deadline. The wrapper always settles within
|
|
4
|
+
* `deadlineMs + epsilon`, whether the inner Promise resolves, rejects,
|
|
5
|
+
* or never settles at all. Rejection of the inner Promise propagates
|
|
6
|
+
* untouched so callers can still see real provider errors.
|
|
7
|
+
*
|
|
8
|
+
* Why this exists: capability providers shell out to external tools
|
|
9
|
+
* (semgrep, jscpd, graphify, npm audit, pip-audit, …) and occasionally
|
|
10
|
+
* produce a Promise that never settles — typically because the
|
|
11
|
+
* provider awaits multiple async operations in turn and one of them
|
|
12
|
+
* (a `Promise.all`, a non-`runDetached` subprocess, a network call)
|
|
13
|
+
* silently hangs. `runDetached` has its own safety-deadline that
|
|
14
|
+
* forces its Promise to resolve, but providers can produce abandoned
|
|
15
|
+
* Promises outside `runDetached` too. The dispatcher used to wrap
|
|
16
|
+
* those calls in `Promise.allSettled`, which only collapses settled
|
|
17
|
+
* Promises — an unsettled Promise inside leaves the whole capability
|
|
18
|
+
* gather pending forever, the Node event loop empties, and the
|
|
19
|
+
* subprocess exits cleanly with no work done — a silent rc=0 with
|
|
20
|
+
* no report on disk. The reproducible offender on at least one
|
|
21
|
+
* heavy JS-stack customer audit has been `license-checker` walking
|
|
22
|
+
* a deep `node_modules` tree, which occasionally produces an
|
|
23
|
+
* unsettling Promise under concurrent subprocess load.
|
|
24
|
+
*
|
|
25
|
+
* The dispatcher applies this helper per-provider so any single
|
|
26
|
+
* provider that stalls is bounded; the rest of the Promise.allSettled
|
|
27
|
+
* still completes; the stalled source ends up in
|
|
28
|
+
* `DispatchOutcome.skipped` with a deadline reason that surfaces
|
|
29
|
+
* downstream in `toolsUnavailable`. Two non-dispatcher gathers
|
|
30
|
+
* (`gatherDepVulnsWithAvailability`, `gatherLicensesWithAvailability`)
|
|
31
|
+
* iterate packs themselves; they apply the same pattern at their
|
|
32
|
+
* own iteration site.
|
|
33
|
+
*/
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.DEFAULT_PROVIDER_DEADLINE_MS = void 0;
|
|
36
|
+
exports.withDeadline = withDeadline;
|
|
37
|
+
/**
|
|
38
|
+
* Race `promise` against a `deadlineMs` timer. Returns:
|
|
39
|
+
* - `{ stalled: false, value }` if the Promise resolves before the deadline
|
|
40
|
+
* - `{ stalled: true, stalledMs }` if the deadline fires first
|
|
41
|
+
*
|
|
42
|
+
* Rejections of the inner Promise propagate as rejections of the
|
|
43
|
+
* returned Promise — callers handle them separately (e.g. via
|
|
44
|
+
* `Promise.allSettled`). The internal timer is cleared on settle so a
|
|
45
|
+
* resolved Promise doesn't leave a stray pending timer keeping Node
|
|
46
|
+
* alive past process exit.
|
|
47
|
+
*/
|
|
48
|
+
function withDeadline(promise, deadlineMs) {
|
|
49
|
+
let timer;
|
|
50
|
+
const deadlinePromise = new Promise((resolve) => {
|
|
51
|
+
timer = setTimeout(() => {
|
|
52
|
+
resolve({ stalled: true, stalledMs: deadlineMs });
|
|
53
|
+
}, deadlineMs);
|
|
54
|
+
});
|
|
55
|
+
const racedInner = promise.then((value) => {
|
|
56
|
+
if (timer !== undefined)
|
|
57
|
+
clearTimeout(timer);
|
|
58
|
+
return { stalled: false, value };
|
|
59
|
+
}, (err) => {
|
|
60
|
+
if (timer !== undefined)
|
|
61
|
+
clearTimeout(timer);
|
|
62
|
+
throw err;
|
|
63
|
+
});
|
|
64
|
+
return Promise.race([racedInner, deadlinePromise]);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Default per-provider deadline for capability gathers. Chosen so the
|
|
68
|
+
* deadline only fires on genuine abandoned-Promise hangs, not on slow
|
|
69
|
+
* legitimate tool runs:
|
|
70
|
+
* - jscpd's `runDetached` timeout is 600s; its safety-deadline adds 30s
|
|
71
|
+
* - semgrep's `runDetached` timeout is 300s
|
|
72
|
+
* - depVulns providers (npm/pip/gem audit, govulncheck, cargo-audit,
|
|
73
|
+
* dotnet) typically settle within 60–180s on large monorepos
|
|
74
|
+
*
|
|
75
|
+
* 720s (12 min) sits above the slowest legitimate provider by ~90s of
|
|
76
|
+
* slack for parsing + aggregation. Real provider runs on the customer
|
|
77
|
+
* benchmark repos finish well inside this; only the stuck case trips
|
|
78
|
+
* it.
|
|
79
|
+
*/
|
|
80
|
+
exports.DEFAULT_PROVIDER_DEADLINE_MS = 720_000;
|
|
81
|
+
//# sourceMappingURL=deadline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deadline.js","sourceRoot":"","sources":["../../../src/analyzers/tools/deadline.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;;;AAiBH,oCAqBC;AAhCD;;;;;;;;;;GAUG;AACH,SAAgB,YAAY,CAC1B,OAAmB,EACnB,UAAkB;IAElB,IAAI,KAAgD,CAAC;IACrD,MAAM,eAAe,GAAG,IAAI,OAAO,CAAqB,CAAC,OAAO,EAAE,EAAE;QAClE,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YACtB,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;QACpD,CAAC,EAAE,UAAU,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAC7B,CAAC,KAAK,EAAsB,EAAE;QAC5B,IAAI,KAAK,KAAK,SAAS;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACnC,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;QACN,IAAI,KAAK,KAAK,SAAS;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,GAAG,CAAC;IACZ,CAAC,CACF,CAAC;IACF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACU,QAAA,4BAA4B,GAAG,OAAO,CAAC"}
|
|
@@ -58,11 +58,11 @@ export declare function getGrepExcludeDirFlags(cwd: string): string;
|
|
|
58
58
|
* multi-segment sourcePaths.
|
|
59
59
|
*
|
|
60
60
|
* D055 (2.4.7): pre-fix, multi-segment paths in `.dxkit-ignore` were
|
|
61
|
-
* flattened to basenames here, so `Dev/Addons/
|
|
62
|
-
* became `{Dev, Addons,
|
|
61
|
+
* flattened to basenames here, so `Dev/Addons/VendorAddon/SAPB1/` silently
|
|
62
|
+
* became `{Dev, Addons, VendorAddon, SAPB1}` — cloc then excluded EVERY
|
|
63
63
|
* directory named `Dev` in the tree, killing 90% of source visibility
|
|
64
|
-
* on
|
|
65
|
-
* structure for cloc.
|
|
64
|
+
* on the .NET WinForms benchmark. The split-flag construction preserves
|
|
65
|
+
* the path structure for cloc.
|
|
66
66
|
*
|
|
67
67
|
* The regex is anchored on path-segment boundaries with `(?:^|/)` /
|
|
68
68
|
* `(?:/|$)` so `Dev/Addons/Foo` doesn't accidentally match `Dev/AddonsX`
|
|
@@ -83,8 +83,8 @@ export declare function getJscpdIgnorePatterns(cwd: string): string[];
|
|
|
83
83
|
* `.dxkit-ignore` entries.
|
|
84
84
|
*
|
|
85
85
|
* D055 (2.4.7): pre-fix, basenames-only flattening here meant
|
|
86
|
-
* `Dev/Addons/
|
|
87
|
-
* — graphify then skipped every `Dev/` subtree in
|
|
86
|
+
* `Dev/Addons/VendorAddon/SAPB1/` became `{Dev, Addons, VendorAddon, SAPB1}`
|
|
87
|
+
* — graphify then skipped every `Dev/` subtree in the .NET WinForms benchmark (10 files
|
|
88
88
|
* walked instead of ~1700, Functions=13). The two-set shape lets the
|
|
89
89
|
* walker check basenames via segment membership AND check paths via
|
|
90
90
|
* substring match on the file's relpath.
|
|
@@ -212,11 +212,11 @@ function getGrepExcludeDirFlags(cwd) {
|
|
|
212
212
|
* multi-segment sourcePaths.
|
|
213
213
|
*
|
|
214
214
|
* D055 (2.4.7): pre-fix, multi-segment paths in `.dxkit-ignore` were
|
|
215
|
-
* flattened to basenames here, so `Dev/Addons/
|
|
216
|
-
* became `{Dev, Addons,
|
|
215
|
+
* flattened to basenames here, so `Dev/Addons/VendorAddon/SAPB1/` silently
|
|
216
|
+
* became `{Dev, Addons, VendorAddon, SAPB1}` — cloc then excluded EVERY
|
|
217
217
|
* directory named `Dev` in the tree, killing 90% of source visibility
|
|
218
|
-
* on
|
|
219
|
-
* structure for cloc.
|
|
218
|
+
* on the .NET WinForms benchmark. The split-flag construction preserves
|
|
219
|
+
* the path structure for cloc.
|
|
220
220
|
*
|
|
221
221
|
* The regex is anchored on path-segment boundaries with `(?:^|/)` /
|
|
222
222
|
* `(?:/|$)` so `Dev/Addons/Foo` doesn't accidentally match `Dev/AddonsX`
|
|
@@ -290,8 +290,8 @@ function getJscpdIgnorePatterns(cwd) {
|
|
|
290
290
|
* `.dxkit-ignore` entries.
|
|
291
291
|
*
|
|
292
292
|
* D055 (2.4.7): pre-fix, basenames-only flattening here meant
|
|
293
|
-
* `Dev/Addons/
|
|
294
|
-
* — graphify then skipped every `Dev/` subtree in
|
|
293
|
+
* `Dev/Addons/VendorAddon/SAPB1/` became `{Dev, Addons, VendorAddon, SAPB1}`
|
|
294
|
+
* — graphify then skipped every `Dev/` subtree in the .NET WinForms benchmark (10 files
|
|
295
295
|
* walked instead of ~1700, Functions=13). The two-set shape lets the
|
|
296
296
|
* walker check basenames via segment membership AND check paths via
|
|
297
297
|
* substring match on the file's relpath.
|
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* non-identical tuples effectively impossible for repo-scale sets.
|
|
2
|
+
* Durable per-finding identity across runs — used by both intra-run dedup
|
|
3
|
+
* (the security aggregator collapses cross-tool overlaps via fingerprint)
|
|
4
|
+
* and cross-run diff tooling (baselines compare today's fingerprint set
|
|
5
|
+
* against yesterday's to surface added / removed / persisted findings).
|
|
6
|
+
*
|
|
7
|
+
* Two fingerprint families live here:
|
|
8
|
+
*
|
|
9
|
+
* 1. Dependency-advisory fingerprints — stable hash of
|
|
10
|
+
* `(package, installedVersion, id)`. Used by `gatherDepVulns` +
|
|
11
|
+
* BoM. Excludes severity / cvssScore / enrichment fields
|
|
12
|
+
* (epssScore, kev, reachable, riskScore), producer `tool`, and
|
|
13
|
+
* `upgradeAdvice` / `upgradePlan` so re-scoring the same advisory
|
|
14
|
+
* against the same install never mints a new identity.
|
|
15
|
+
*
|
|
16
|
+
* 2. Code/secret/config-finding fingerprints — stable hash of
|
|
17
|
+
* `(canonicalRule, file, lineWindow)`. The canonical-rule map
|
|
18
|
+
* collapses cross-tool overlaps (e.g. semgrep + a per-language
|
|
19
|
+
* grep-based pattern both reporting the same TLS-bypass
|
|
20
|
+
* construct). The line-window absorbs the small offset between
|
|
21
|
+
* tools that report the declaration vs. the assignment.
|
|
22
|
+
*
|
|
23
|
+
* Both families share format: 16-char lowercase hex (first 8 bytes of
|
|
24
|
+
* SHA-1). Short enough to embed inline in reports, long enough to make
|
|
25
|
+
* collisions between non-identical tuples effectively impossible at
|
|
26
|
+
* repo scale. Producers may render either inline interchangeably.
|
|
28
27
|
*/
|
|
29
28
|
import type { DepVulnFinding } from '../../languages/capabilities/types';
|
|
30
29
|
/**
|
|
@@ -60,4 +59,70 @@ export declare function stampFingerprints(findings: DepVulnFinding[]): void;
|
|
|
60
59
|
* findings outside the `gatherDepVulns` path).
|
|
61
60
|
*/
|
|
62
61
|
export declare function collectFingerprints(findings: ReadonlyArray<DepVulnFinding>): string[];
|
|
62
|
+
/**
|
|
63
|
+
* Maps raw `(tool, rule)` pairs to a canonical rule id. Two raw
|
|
64
|
+
* findings with the same canonical rule (and same file + line window)
|
|
65
|
+
* fingerprint identically — the aggregator's dedup pipeline collapses
|
|
66
|
+
* them into a single CodeFinding with `producedBy` listing every
|
|
67
|
+
* contributing tool. Adding a new collapse is a one-line addition; no
|
|
68
|
+
* algorithm changes.
|
|
69
|
+
*
|
|
70
|
+
* Unmapped pairs fall through to `raw:${tool}:${rule}` — conservative
|
|
71
|
+
* default. Never accidentally collapses unrelated findings.
|
|
72
|
+
*/
|
|
73
|
+
export declare const CANONICAL_RULE_MAP: ReadonlyMap<string, string>;
|
|
74
|
+
/** Resolve a raw `(tool, rule)` pair to its canonical rule id. */
|
|
75
|
+
export declare function canonicalRuleFor(tool: string, rule: string): string;
|
|
76
|
+
/**
|
|
77
|
+
* Width of the line-number bucket used by code-finding fingerprints.
|
|
78
|
+
* Tools report the same construct at slightly different lines (one
|
|
79
|
+
* tool on the declaration, another on the assignment). Bucketing
|
|
80
|
+
* absorbs that drift without collapsing unrelated findings on
|
|
81
|
+
* nearby lines.
|
|
82
|
+
*/
|
|
83
|
+
export declare const CODE_FINGERPRINT_LINE_WINDOW = 3;
|
|
84
|
+
/**
|
|
85
|
+
* Bucket a line number to its canonical line-window value. Findings
|
|
86
|
+
* sharing the same `(canonicalRule, file, lineWindow)` tuple share a
|
|
87
|
+
* fingerprint.
|
|
88
|
+
*
|
|
89
|
+
* Note on boundary cases: the aggregator additionally probes the two
|
|
90
|
+
* neighbor buckets (±lineWindow) to catch adjacent findings that
|
|
91
|
+
* straddle a bucket boundary; that lookup lives in the aggregator
|
|
92
|
+
* because it owns the merge policy, not here.
|
|
93
|
+
*/
|
|
94
|
+
export declare function lineWindowFor(line: number): number;
|
|
95
|
+
/**
|
|
96
|
+
* Stable 16-char hex hash of `(canonicalRule, file, lineWindow)`.
|
|
97
|
+
* NUL-separated so distinct tuples can't collide via concatenation
|
|
98
|
+
* tricks. Same byte format as `computeFingerprint` so dep-vuln and
|
|
99
|
+
* code-finding fingerprints share a downstream type contract.
|
|
100
|
+
*/
|
|
101
|
+
export declare function computeCodeFingerprint(canonicalRule: string, file: string, line: number): string;
|
|
102
|
+
/**
|
|
103
|
+
* HMAC-SHA256 of a detected secret value, keyed by a per-repo salt.
|
|
104
|
+
* The output is 16-char lowercase hex (first 8 bytes of the 32-byte
|
|
105
|
+
* HMAC) so it shares the byte format of the other fingerprint helpers
|
|
106
|
+
* and can be embedded inline in reports without taking real estate.
|
|
107
|
+
*
|
|
108
|
+
* Cryptographic posture: HMAC (not bare hash) so the producer cannot
|
|
109
|
+
* recover the secret from its identity even if the salt is leaked,
|
|
110
|
+
* and the salt cannot be recovered from the identity even if the
|
|
111
|
+
* secret is known. Truncating to 8 bytes is safe at repo scale —
|
|
112
|
+
* collision probability for distinct secrets is ~2^-32 per pair,
|
|
113
|
+
* negligible for any realistic finding set.
|
|
114
|
+
*
|
|
115
|
+
* Used by the secret-hmac identity scheme: a leaked token that moves
|
|
116
|
+
* files between runs produces the same HMAC, so the matcher can
|
|
117
|
+
* recognize "same secret, different location" as a relocated finding
|
|
118
|
+
* rather than a deleted+added pair. The salt is per-repo so
|
|
119
|
+
* cross-repo identity collisions are impossible (the same secret in
|
|
120
|
+
* two repos hashes to two different HMACs).
|
|
121
|
+
*
|
|
122
|
+
* The producer never stores the secret value itself — only the HMAC.
|
|
123
|
+
* That's the whole reason this scheme is preferred over a bare
|
|
124
|
+
* content hash of the secret: zero secret-recovery risk in the
|
|
125
|
+
* baseline file.
|
|
126
|
+
*/
|
|
127
|
+
export declare function computeSecretHmac(secret: string, salt: string): string;
|
|
63
128
|
//# sourceMappingURL=fingerprint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,kBAAkB,GAAG,IAAI,CAAC,GACnE,MAAM,CAGR;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI,CAIlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,MAAM,EAAE,CAMrF;AAID;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CASzD,CAAC;AAEH,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhG;AAID;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtE"}
|
|
@@ -1,36 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Durable per-finding identity across runs — used by both intra-run dedup
|
|
4
|
+
* (the security aggregator collapses cross-tool overlaps via fingerprint)
|
|
5
|
+
* and cross-run diff tooling (baselines compare today's fingerprint set
|
|
6
|
+
* against yesterday's to surface added / removed / persisted findings).
|
|
4
7
|
*
|
|
5
|
-
*
|
|
6
|
-
* stamps every finding with a stable hash of `(package, installedVersion,
|
|
7
|
-
* id)` before scoring + reporting. The same advisory against the same
|
|
8
|
-
* installed version produces the same fingerprint on every run, so
|
|
9
|
-
* consumers (agent-driven upgrade bots, suppressions, CI gates) can diff
|
|
10
|
-
* a current bom against a stored prior to detect:
|
|
8
|
+
* Two fingerprint families live here:
|
|
11
9
|
*
|
|
12
|
-
* -
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* 1. Dependency-advisory fingerprints — stable hash of
|
|
11
|
+
* `(package, installedVersion, id)`. Used by `gatherDepVulns` +
|
|
12
|
+
* BoM. Excludes severity / cvssScore / enrichment fields
|
|
13
|
+
* (epssScore, kev, reachable, riskScore), producer `tool`, and
|
|
14
|
+
* `upgradeAdvice` / `upgradePlan` so re-scoring the same advisory
|
|
15
|
+
* against the same install never mints a new identity.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* npm-audit + snyk) should collapse to one identity
|
|
23
|
-
* - `upgradeAdvice` / `upgradePlan` — resolution suggestions change
|
|
24
|
-
* across releases of the fix tooling; identity must outlive them
|
|
17
|
+
* 2. Code/secret/config-finding fingerprints — stable hash of
|
|
18
|
+
* `(canonicalRule, file, lineWindow)`. The canonical-rule map
|
|
19
|
+
* collapses cross-tool overlaps (e.g. semgrep + a per-language
|
|
20
|
+
* grep-based pattern both reporting the same TLS-bypass
|
|
21
|
+
* construct). The line-window absorbs the small offset between
|
|
22
|
+
* tools that report the declaration vs. the assignment.
|
|
25
23
|
*
|
|
26
|
-
*
|
|
27
|
-
* to embed inline in reports, long enough to make
|
|
28
|
-
* non-identical tuples effectively impossible
|
|
24
|
+
* Both families share format: 16-char lowercase hex (first 8 bytes of
|
|
25
|
+
* SHA-1). Short enough to embed inline in reports, long enough to make
|
|
26
|
+
* collisions between non-identical tuples effectively impossible at
|
|
27
|
+
* repo scale. Producers may render either inline interchangeably.
|
|
29
28
|
*/
|
|
30
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.CODE_FINGERPRINT_LINE_WINDOW = exports.CANONICAL_RULE_MAP = void 0;
|
|
31
31
|
exports.computeFingerprint = computeFingerprint;
|
|
32
32
|
exports.stampFingerprints = stampFingerprints;
|
|
33
33
|
exports.collectFingerprints = collectFingerprints;
|
|
34
|
+
exports.canonicalRuleFor = canonicalRuleFor;
|
|
35
|
+
exports.lineWindowFor = lineWindowFor;
|
|
36
|
+
exports.computeCodeFingerprint = computeCodeFingerprint;
|
|
37
|
+
exports.computeSecretHmac = computeSecretHmac;
|
|
34
38
|
const crypto_1 = require("crypto");
|
|
35
39
|
/**
|
|
36
40
|
* Stable 16-char hex fingerprint for one DepVulnFinding. Input tuple
|
|
@@ -79,4 +83,89 @@ function collectFingerprints(findings) {
|
|
|
79
83
|
}
|
|
80
84
|
return [...set].sort();
|
|
81
85
|
}
|
|
86
|
+
// ─── Code/secret/config-finding fingerprints ─────────────────────────────────
|
|
87
|
+
/**
|
|
88
|
+
* Maps raw `(tool, rule)` pairs to a canonical rule id. Two raw
|
|
89
|
+
* findings with the same canonical rule (and same file + line window)
|
|
90
|
+
* fingerprint identically — the aggregator's dedup pipeline collapses
|
|
91
|
+
* them into a single CodeFinding with `producedBy` listing every
|
|
92
|
+
* contributing tool. Adding a new collapse is a one-line addition; no
|
|
93
|
+
* algorithm changes.
|
|
94
|
+
*
|
|
95
|
+
* Unmapped pairs fall through to `raw:${tool}:${rule}` — conservative
|
|
96
|
+
* default. Never accidentally collapses unrelated findings.
|
|
97
|
+
*/
|
|
98
|
+
exports.CANONICAL_RULE_MAP = new Map([
|
|
99
|
+
// TLS / certificate validation bypass
|
|
100
|
+
['tls-bypass-registry:tls-validation-disabled', 'canonical:tls-bypass'],
|
|
101
|
+
['semgrep:bypass-tls-verification', 'canonical:tls-bypass'],
|
|
102
|
+
['semgrep:nodejsscan.node_tls_reject_unauthorized', 'canonical:tls-bypass'],
|
|
103
|
+
// Private-key file on disk — find + gitleaks may both surface
|
|
104
|
+
['find:private-key-file', 'canonical:private-key-on-disk'],
|
|
105
|
+
['gitleaks:private-key', 'canonical:private-key-on-disk'],
|
|
106
|
+
]);
|
|
107
|
+
/** Resolve a raw `(tool, rule)` pair to its canonical rule id. */
|
|
108
|
+
function canonicalRuleFor(tool, rule) {
|
|
109
|
+
return exports.CANONICAL_RULE_MAP.get(`${tool}:${rule}`) ?? `raw:${tool}:${rule}`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Width of the line-number bucket used by code-finding fingerprints.
|
|
113
|
+
* Tools report the same construct at slightly different lines (one
|
|
114
|
+
* tool on the declaration, another on the assignment). Bucketing
|
|
115
|
+
* absorbs that drift without collapsing unrelated findings on
|
|
116
|
+
* nearby lines.
|
|
117
|
+
*/
|
|
118
|
+
exports.CODE_FINGERPRINT_LINE_WINDOW = 3;
|
|
119
|
+
/**
|
|
120
|
+
* Bucket a line number to its canonical line-window value. Findings
|
|
121
|
+
* sharing the same `(canonicalRule, file, lineWindow)` tuple share a
|
|
122
|
+
* fingerprint.
|
|
123
|
+
*
|
|
124
|
+
* Note on boundary cases: the aggregator additionally probes the two
|
|
125
|
+
* neighbor buckets (±lineWindow) to catch adjacent findings that
|
|
126
|
+
* straddle a bucket boundary; that lookup lives in the aggregator
|
|
127
|
+
* because it owns the merge policy, not here.
|
|
128
|
+
*/
|
|
129
|
+
function lineWindowFor(line) {
|
|
130
|
+
return Math.floor(line / exports.CODE_FINGERPRINT_LINE_WINDOW) * exports.CODE_FINGERPRINT_LINE_WINDOW;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Stable 16-char hex hash of `(canonicalRule, file, lineWindow)`.
|
|
134
|
+
* NUL-separated so distinct tuples can't collide via concatenation
|
|
135
|
+
* tricks. Same byte format as `computeFingerprint` so dep-vuln and
|
|
136
|
+
* code-finding fingerprints share a downstream type contract.
|
|
137
|
+
*/
|
|
138
|
+
function computeCodeFingerprint(canonicalRule, file, line) {
|
|
139
|
+
const input = `${canonicalRule}\0${file}\0${lineWindowFor(line)}`;
|
|
140
|
+
return (0, crypto_1.createHash)('sha1').update(input).digest('hex').slice(0, 16);
|
|
141
|
+
}
|
|
142
|
+
// ─── Secret HMAC primitive ───────────────────────────────────────────────────
|
|
143
|
+
/**
|
|
144
|
+
* HMAC-SHA256 of a detected secret value, keyed by a per-repo salt.
|
|
145
|
+
* The output is 16-char lowercase hex (first 8 bytes of the 32-byte
|
|
146
|
+
* HMAC) so it shares the byte format of the other fingerprint helpers
|
|
147
|
+
* and can be embedded inline in reports without taking real estate.
|
|
148
|
+
*
|
|
149
|
+
* Cryptographic posture: HMAC (not bare hash) so the producer cannot
|
|
150
|
+
* recover the secret from its identity even if the salt is leaked,
|
|
151
|
+
* and the salt cannot be recovered from the identity even if the
|
|
152
|
+
* secret is known. Truncating to 8 bytes is safe at repo scale —
|
|
153
|
+
* collision probability for distinct secrets is ~2^-32 per pair,
|
|
154
|
+
* negligible for any realistic finding set.
|
|
155
|
+
*
|
|
156
|
+
* Used by the secret-hmac identity scheme: a leaked token that moves
|
|
157
|
+
* files between runs produces the same HMAC, so the matcher can
|
|
158
|
+
* recognize "same secret, different location" as a relocated finding
|
|
159
|
+
* rather than a deleted+added pair. The salt is per-repo so
|
|
160
|
+
* cross-repo identity collisions are impossible (the same secret in
|
|
161
|
+
* two repos hashes to two different HMACs).
|
|
162
|
+
*
|
|
163
|
+
* The producer never stores the secret value itself — only the HMAC.
|
|
164
|
+
* That's the whole reason this scheme is preferred over a bare
|
|
165
|
+
* content hash of the secret: zero secret-recovery risk in the
|
|
166
|
+
* baseline file.
|
|
167
|
+
*/
|
|
168
|
+
function computeSecretHmac(secret, salt) {
|
|
169
|
+
return (0, crypto_1.createHmac)('sha256', salt).update(secret).digest('hex').slice(0, 16);
|
|
170
|
+
}
|
|
82
171
|
//# sourceMappingURL=fingerprint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;AAeH,gDAKC;AAYD,8CAIC;AAYD,kDAMC;AA2BD,4CAEC;AAqBD,sCAEC;AAQD,wDAGC;AA6BD,8CAEC;AAlJD,mCAAgD;AAGhD;;;;;;;;;GASG;AACH,SAAgB,kBAAkB,CAChC,OAAoE;IAEpE,MAAM,KAAK,GAAG,GAAG,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,gBAAgB,IAAI,EAAE,KAAK,OAAO,CAAC,EAAE,EAAE,CAAC;IACrF,OAAO,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,iBAAiB,CAAC,QAA0B;IAC1D,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,CAAC,CAAC,WAAW,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,mBAAmB,CAAC,QAAuC;IACzE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,WAAW;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;;GAUG;AACU,QAAA,kBAAkB,GAAgC,IAAI,GAAG,CAAiB;IACrF,sCAAsC;IACtC,CAAC,6CAA6C,EAAE,sBAAsB,CAAC;IACvE,CAAC,iCAAiC,EAAE,sBAAsB,CAAC;IAC3D,CAAC,iDAAiD,EAAE,sBAAsB,CAAC;IAE3E,8DAA8D;IAC9D,CAAC,uBAAuB,EAAE,+BAA+B,CAAC;IAC1D,CAAC,sBAAsB,EAAE,+BAA+B,CAAC;CAC1D,CAAC,CAAC;AAEH,kEAAkE;AAClE,SAAgB,gBAAgB,CAAC,IAAY,EAAE,IAAY;IACzD,OAAO,0BAAkB,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,IAAI,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC;AAC5E,CAAC;AAED;;;;;;GAMG;AACU,QAAA,4BAA4B,GAAG,CAAC,CAAC;AAE9C;;;;;;;;;GASG;AACH,SAAgB,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,oCAA4B,CAAC,GAAG,oCAA4B,CAAC;AACxF,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,aAAqB,EAAE,IAAY,EAAE,IAAY;IACtF,MAAM,KAAK,GAAG,GAAG,aAAa,KAAK,IAAI,KAAK,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;IAClE,OAAO,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,SAAgB,iBAAiB,CAAC,MAAc,EAAE,IAAY;IAC5D,OAAO,IAAA,mBAAU,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/generic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA+DjD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,aAAa,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,GACzC,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/generic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA+DjD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,aAAa,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,GACzC,OAAO,CAAC,aAAa,CAAC,CAsOxB"}
|
|
@@ -57,7 +57,7 @@ const path = __importStar(require("path"));
|
|
|
57
57
|
* Resolve the git toplevel for `cwd`. D026 (2.4.7): cross-cutting repo
|
|
58
58
|
* artifacts (`.github/`, `README.md`, `CONTRIBUTING.md`, `Makefile`,
|
|
59
59
|
* `.env.example`, etc.) conventionally live at the repo root, not in
|
|
60
|
-
* the subdirectory a user happens to scan.
|
|
60
|
+
* the subdirectory a user happens to scan. The .NET WinForms benchmark's baseline F8:
|
|
61
61
|
* customer ran `dxkit health Code/Source/`; both Documentation and DX
|
|
62
62
|
* dimensions returned 0/100 because none of those probes found
|
|
63
63
|
* matches in `Code/Source/`. The fix scopes those probes to the
|
|
@@ -151,7 +151,12 @@ function gatherGenericMetrics(cwd, languageFlags) {
|
|
|
151
151
|
filesOver500Lines++;
|
|
152
152
|
}
|
|
153
153
|
const sourceFiles = sourceList.length;
|
|
154
|
-
|
|
154
|
+
// Every file over the canonical large-file threshold, sorted
|
|
155
|
+
// descending. Filtered (not pre-sliced) at this layer so the
|
|
156
|
+
// baseline `large-file` producer captures one entry per file and
|
|
157
|
+
// the per-kind count matches `filesOver500Lines` above. The
|
|
158
|
+
// markdown renderer caps to top 10 at the display site.
|
|
159
|
+
const largestFiles = filteredFiles.filter((f) => f.lines > 500).sort((a, b) => b.lines - a.lines);
|
|
155
160
|
// ─── Console / debug / type-escape / eval counts (D074 closure) ───────────
|
|
156
161
|
// skipComments: true filters lines beginning with //, /*, or # so
|
|
157
162
|
// commented-out occurrences don't inflate the count.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../../../src/analyzers/tools/generic.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+EA,
|
|
1
|
+
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../../../src/analyzers/tools/generic.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,39 @@
|
|
|
1
1
|
import type { CapabilityProvider } from '../../languages/capabilities/provider';
|
|
2
2
|
import type { SecretsResult } from '../../languages/capabilities/types';
|
|
3
|
+
/**
|
|
4
|
+
* Per-finding raw value carried alongside the public envelope. Stays
|
|
5
|
+
* out of `SecretsResult` (and therefore out of `SecurityAggregate`,
|
|
6
|
+
* `SecurityReport`, the dashboard, JSON outputs) so the secret value
|
|
7
|
+
* never leaks through the normal reporting surfaces. The only legit
|
|
8
|
+
* consumer is the baseline-side secret-HMAC producer, which immediately
|
|
9
|
+
* HMACs the value and discards it.
|
|
10
|
+
*
|
|
11
|
+
* Lives in this outcome rather than fetched separately so the memoized
|
|
12
|
+
* gitleaks invocation (`gatherGitleaksResult` runs at most once per
|
|
13
|
+
* cwd) covers both the public envelope path and the HMAC path.
|
|
14
|
+
*/
|
|
15
|
+
export interface GitleaksRawSecret {
|
|
16
|
+
readonly file: string;
|
|
17
|
+
readonly line: number;
|
|
18
|
+
readonly rule: string;
|
|
19
|
+
/** The matched secret value as reported by gitleaks. Process-only;
|
|
20
|
+
* callers MUST NOT write this to disk, log it, or include it in
|
|
21
|
+
* any output payload. */
|
|
22
|
+
readonly secret: string;
|
|
23
|
+
}
|
|
3
24
|
/**
|
|
4
25
|
* Outcome union used by `gatherGitleaksResult`. The capability provider
|
|
5
26
|
* collapses this to `SecretsResult | null`; the Layer 2 reshape in
|
|
6
27
|
* `tools/parallel.ts` reads `unavailable.reason` so the
|
|
7
28
|
* `toolsUnavailable` strings carry install-missing vs parse-failure
|
|
8
|
-
* detail.
|
|
29
|
+
* detail. The `rawSecrets` field is read only by the baseline-side
|
|
30
|
+
* secret-HMAC producer; other consumers ignore it.
|
|
9
31
|
*/
|
|
10
32
|
export type SecretsGatherOutcome = {
|
|
11
33
|
kind: 'success';
|
|
12
34
|
envelope: SecretsResult;
|
|
13
35
|
suppressedCount: number;
|
|
36
|
+
rawSecrets: ReadonlyArray<GitleaksRawSecret>;
|
|
14
37
|
} | {
|
|
15
38
|
kind: 'unavailable';
|
|
16
39
|
reason: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitleaks.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/gitleaks.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAiB,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAUvF
|
|
1
|
+
{"version":3,"file":"gitleaks.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/gitleaks.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAiB,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAUvF;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;8BAE0B;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;CAC9C,GACD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgB5C;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAMtE;AA0FD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,aAAa,CAM9D,CAAC"}
|