@blackbelt-technology/pi-dashboard-server
Supply chain provenance
Status for the latest visible version.
Maintainers
Accepted risks
Findings the reviewer chose to accept rather than block on.
| Source | Rule | Reason | Accepted by | When |
|---|---|---|---|---|
| phantom-deps | phantom-dep:diff | AI (phantom-deps): Used via config/indirect import; heuristic false positive for this package. | ai | |
| phantom-deps | phantom-dep:@blackbelt-technology/pi-dashboard-extension | AI (phantom-deps): Same-org scoped dep; heuristic false positive. | ai | |
| phantom-deps | phantom-dep:@fastify/http-proxy | AI (phantom-deps): Plugin-style dep loaded via config; stable false positive. | ai | |
| phantom-deps | phantom-dep:@fastify/websocket | AI (phantom-deps): Plugin-style dep loaded via config; stable false positive. | ai | |
| phantom-deps | phantom-dep:bonjour-service | AI (phantom-deps): Used via config/indirect import; heuristic false positive for this package. | ai | |
| phantom-deps | phantom-dep:tsx | AI (phantom-deps): tsx is a runtime loader/executor; used via config/bin rather than direct import — stable false positive. | ai | |
| semgrep | semgrep:hex-decode | AI (semgrep): Used in timing-safe key comparison (crypto.timingSafeEqual) — standard secure hashing pattern, not payload decoding. | ai | |
| semgrep | semgrep:child-process-import | AI (semgrep): keeper.cjs spawns the 'pi' process — core product functionality, not malicious exec. | ai | |
| semgrep | semgrep:child-process-spawn | AI (semgrep): Spawns 'pi' binary with logged stdio — documented product behavior, not exfiltration. | ai | |
| phantom-deps | phantom-dep:jiti | AI (phantom-deps): jiti is a runtime loader; used via config rather than direct import — stable false positive. | ai | |
| phantom-deps | phantom-dep:@fission-ai/openspec | AI (phantom-deps): Plugin/extension dep loaded dynamically; phantom detection is a false positive for this package. | ai | |
| phantom-deps | phantom-dep:@earendil-works/pi-coding-agent | AI (phantom-deps): Optional coding agent plugin; loaded dynamically, not directly imported — stable false positive. | ai | |
| semgrep | semgrep:silent-process-exec | AI (semgrep): Fires in test file spawning a dummy sleep process to simulate headless session — not a reverse shell. | ai | |
| install-scripts | install-script:postinstall | AI (install-scripts): Fixes PTY permissions for node-pty — documented pattern for native terminal bindings. | ai | |
| semgrep | semgrep:shady-links-raw-ip | AI (semgrep): Fires in CORS test asserting 127.0.0.1 is allowed — localhost test fixture, not exfiltration. | ai | |
| semgrep | semgrep:etc-passwd-access | AI (semgrep): Fires only in test files asserting path traversal is rejected — not production credential harvesting. | ai | |
| semgrep | semgrep:env-spread | AI (semgrep): Fires in test file saving/restoring process.env for test isolation — standard test pattern. | ai | |
| semgrep | semgrep:silent-process-exec-var | AI (semgrep): Same test-file dummy process as silent-process-exec; stable false positive for this package. | ai |
Versions (showing 6 of 6)
| Version | Deps | Published |
|---|---|---|
| 0.5.4 | 21 / 4 | |
| 0.4.5 | 17 / 4 | |
| 0.4.4 | 17 / 4 | |
| 0.4.3 | 17 / 4 | |
| 0.4.1 | 17 / 4 | |
| 0.3.0 | 16 / 4 |
v0.5.4
1 findingPublished via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.
v0.4.5
17 findingsScript: node scripts/fix-pty-permissions.cjs
Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/__tests__/file-endpoint.test.ts#L31 29 | 30 | it("should reject path traversal with ../", () => { > 31 | expect(isPathContained("/project", "../../etc/passwd")).toBe(false); 32 | }); 33 |
Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/__tests__/file-endpoint.test.ts#L43 41 | 42 | it("should reject absolute path outside cwd", () => { > 43 | expect(isPathContained("/project", "/etc/passwd")).toBe(false); 44 | }); 45 |
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/__tests__/headless-shutdown-fallback.test.ts#L46 44 | 45 | // Spawn a real dummy process (sleep) to act as the headless pi session > 46 | const dummy = spawn("sleep", ["60"], { detached: true, stdio: "ignore" }); 47 | dummy.unref(); 48 | const pid = dummy.pid!;
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/__tests__/headless-shutdown-fallback.test.ts#L46 44 | 45 | // Spawn a real dummy process (sleep) to act as the headless pi session > 46 | const dummy = spawn("sleep", ["60"], { detached: true, stdio: "ignore" }); 47 | dummy.unref(); 48 | const pid = dummy.pid!;
Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/__tests__/process-manager.test.ts#L45 43 | it("should shell-escape sessionFile with special characters", () => { 44 | const cmd = buildTmuxCommand("/home/user/project", true, { > 45 | sessionFile: "/path/to/my session; cat /etc/passwd", 46 | mode: "continue", 47 | });
Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/__tests__/process-manager.test.ts#L48 46 | mode: "continue", 47 | }); > 48 | expect(cmd).toContain("--session '/path/to/my session; cat /etc/passwd'"); 49 | }); 50 |
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/__tests__/provider-probe.test.ts#L76 74 | 75 | describe("resolveProbeApiKey", () => { > 76 | const ORIGINAL_ENV = { ...process.env }; 77 | beforeEach(() => { 78 | process.env = { ...ORIGINAL_ENV };
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/cli.ts#L384 382 | detached: true, 383 | stdio: ["ignore", logFd, logFd], > 384 | env: { ...process.env }, 385 | }, 386 | });
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/package-manager-wrapper.ts#L96 94 | cwd: options?.cwd, 95 | stdio: ["ignore", "pipe", "pipe"], > 96 | env: options?.env ? { ...process.env, ...options.env } : process.env, 97 | }); 98 | }
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/restart-helper.ts#L173 171 | const script = buildOrchestratorScript(params); 172 | const execPath = params.execPath ?? process.execPath; > 173 | const child = spawn(execPath, ["-e", script], { 174 | detached: true, 175 | stdio: "ignore",
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/restart-helper.ts#L173 171 | const script = buildOrchestratorScript(params); 172 | const execPath = params.execPath ?? process.execPath; > 173 | const child = spawn(execPath, ["-e", script], { 174 | detached: true, 175 | stdio: "ignore",
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/restart-helper.ts#L176 174 | detached: true, 175 | stdio: "ignore", > 176 | env: { ...process.env }, 177 | windowsHide: true, 178 | });
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/routes/system-routes.ts#L103 101 | 102 | try { > 103 | const child = spawn(editorEntry.cli, args, { 104 | detached: true, 105 | stdio: "ignore",
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/routes/system-routes.ts#L103 101 | 102 | try { > 103 | const child = spawn(editorEntry.cli, args, { 104 | detached: true, 105 | stdio: "ignore",
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/c048dc6fa6a452b1003e30266533b50afed08382/src/terminal-manager.ts#L119 117 | const id = generateId(); 118 | > 119 | const env = { ...process.env, ...platformTerminalEnvHints() } as Record<string, string>; 120 | 121 | const p = pty.spawn(shell, [], {
Published via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.
v0.4.4
1 findingPublished via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.
v0.4.3
1 findingPublished via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.
v0.4.1
17 findingsScript: node scripts/fix-pty-permissions.cjs
Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/__tests__/file-endpoint.test.ts#L31 29 | 30 | it("should reject path traversal with ../", () => { > 31 | expect(isPathContained("/project", "../../etc/passwd")).toBe(false); 32 | }); 33 |
Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/__tests__/file-endpoint.test.ts#L43 41 | 42 | it("should reject absolute path outside cwd", () => { > 43 | expect(isPathContained("/project", "/etc/passwd")).toBe(false); 44 | }); 45 |
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/__tests__/headless-shutdown-fallback.test.ts#L46 44 | 45 | // Spawn a real dummy process (sleep) to act as the headless pi session > 46 | const dummy = spawn("sleep", ["60"], { detached: true, stdio: "ignore" }); 47 | dummy.unref(); 48 | const pid = dummy.pid!;
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/__tests__/headless-shutdown-fallback.test.ts#L46 44 | 45 | // Spawn a real dummy process (sleep) to act as the headless pi session > 46 | const dummy = spawn("sleep", ["60"], { detached: true, stdio: "ignore" }); 47 | dummy.unref(); 48 | const pid = dummy.pid!;
Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/__tests__/process-manager.test.ts#L45 43 | it("should shell-escape sessionFile with special characters", () => { 44 | const cmd = buildTmuxCommand("/home/user/project", true, { > 45 | sessionFile: "/path/to/my session; cat /etc/passwd", 46 | mode: "continue", 47 | });
Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/__tests__/process-manager.test.ts#L48 46 | mode: "continue", 47 | }); > 48 | expect(cmd).toContain("--session '/path/to/my session; cat /etc/passwd'"); 49 | }); 50 |
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/__tests__/provider-probe.test.ts#L76 74 | 75 | describe("resolveProbeApiKey", () => { > 76 | const ORIGINAL_ENV = { ...process.env }; 77 | beforeEach(() => { 78 | process.env = { ...ORIGINAL_ENV };
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/cli.ts#L385 383 | detached: true, 384 | stdio: ["ignore", logFd, logFd], > 385 | env: { ...process.env }, 386 | }, 387 | });
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/package-manager-wrapper.ts#L96 94 | cwd: options?.cwd, 95 | stdio: ["ignore", "pipe", "pipe"], > 96 | env: options?.env ? { ...process.env, ...options.env } : process.env, 97 | }); 98 | }
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/restart-helper.ts#L134 132 | const script = buildOrchestratorScript(params); 133 | const execPath = params.execPath ?? process.execPath; > 134 | const child = spawn(execPath, ["-e", script], { 135 | detached: true, 136 | stdio: "ignore",
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/restart-helper.ts#L134 132 | const script = buildOrchestratorScript(params); 133 | const execPath = params.execPath ?? process.execPath; > 134 | const child = spawn(execPath, ["-e", script], { 135 | detached: true, 136 | stdio: "ignore",
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/restart-helper.ts#L137 135 | detached: true, 136 | stdio: "ignore", > 137 | env: { ...process.env }, 138 | windowsHide: true, 139 | });
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/routes/system-routes.ts#L88 86 | 87 | try { > 88 | const child = spawn(editorEntry.cli, args, { 89 | detached: true, 90 | stdio: "ignore",
Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/routes/system-routes.ts#L88 86 | 87 | try { > 88 | const child = spawn(editorEntry.cli, args, { 89 | detached: true, 90 | stdio: "ignore",
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/BlackBeltTechnology/pi-agent-dashboard/blob/2728c316a2bf0710680cfb94faac5af7132ae7a1/src/terminal-manager.ts#L119 117 | const id = generateId(); 118 | > 119 | const env = { ...process.env, ...platformTerminalEnvHints() } as Record<string, string>; 120 | 121 | const p = pty.spawn(shell, [], {
Published via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.
v0.3.0
1 findingPackage was published without Sigstore provenance. Only ~12% of npm packages have provenance, so this is common but not ideal.