← Home

@lobu/worker

Lobu worker runtime - run in your own Docker image or use our base image

24
Versions
Apache-2.0
License
No
Install Scripts
Missing
Provenance

Supply chain provenance

Status for the latest visible version.

No SLSA provenance npm registry signatures gitHead linked

Without SLSA provenance there is no cryptographic link between this tarball and the public source — the axios compromise (March 2026) relied on exactly this gap.

Maintainers

buremba

Keywords

lobuworkeraiagent

Accepted risks

Findings the reviewer chose to accept rather than block on.

SourceRuleReasonAccepted byWhen
semgrep semgrep:env-spread AI (semgrep): Worker runtime intentionally forwards full env to child processes; pattern is expected and documented. ai
semgrep semgrep:env-bulk-read AI (semgrep): Same context: filtering process.env for child_process spawn is standard worker pattern. ai
phantom-deps phantom-dep:owletto AI (phantom-deps): owletto is a declared runtime dep; phantom-dep heuristic fires because it's used indirectly via config. ai
phantom-deps phantom-dep:@lobu/owletto-openclaw AI (phantom-deps): Same-org package used indirectly; phantom-dep false positive for this package. ai
semgrep semgrep:base64-decode AI (semgrep): Fires in test assertions verifying base64 encoding behavior; no malicious payload. ai
semgrep semgrep:shady-links-raw-ip AI (semgrep): Raw IP (127.0.0.1) appears only in a JSDoc comment as a localhost example URL. ai
semgrep semgrep:etc-passwd-access AI (semgrep): Fires in test files exercising the just-bash hostcat feature; not production credential harvesting. ai

Versions (showing 24 of 24)

Version Deps Published
11.0.0 11 / 2
10.2.0 11 / 2
10.1.0 11 / 2
10.0.0 11 / 2
9.4.1 11 / 2
9.4.0 11 / 2
9.3.0 11 / 2
9.1.1 11 / 2
9.1.0 11 / 2
9.0.0 11 / 2
8.0.0 11 / 2
7.2.0 11 / 2
7.1.0 11 / 2
7.0.0 11 / 2
6.1.1 11 / 2
6.0.0 11 / 2
5.0.0 11 / 2
4.3.0 11 / 2
4.2.0 13 / 2
3.4.1 13 / 2
3.2.0 13 / 2
3.0.8 13 / 2
3.0.7 13 / 2
2.8.0 13 / 2

v11.0.0

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v10.2.0

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v10.1.0

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v10.0.0

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v9.4.1

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v9.4.0

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v9.3.0

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v9.1.1

17 findings
HIGH etc-passwd-access: src/__tests__/embedded-just-bash-bootstrap.test.ts:56 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/embedded-just-bash-bootstrap.test.ts#L56 54 | const ops = await createEmbeddedBashOps({ workspaceDir: workspace }); 55 | const chunks: string[] = []; > 56 | const result = await ops.exec("hostcat /etc/passwd", "/", { 57 | onData: (chunk) => chunks.push(chunk.toString()), 58 | timeout: 5,

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:283 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L283 281 | } 282 | > 283 | test("blocks /etc/passwd", async () => { 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:284 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L284 282 | 283 | test("blocks /etc/passwd", async () => { > 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 286 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:293 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L293 291 | }); 292 | > 293 | test("blocks ../../etc/passwd traversal", async () => { 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:294 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L294 292 | 293 | test("blocks ../../etc/passwd traversal", async () => { > 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 296 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:298 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L298 296 | }); 297 | > 298 | test("blocks symlink-to-/etc/passwd", async () => { 299 | const r = await runIn("/bin/sh", [ 300 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:301 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L301 299 | const r = await runIn("/bin/sh", [ 300 | "-c", > 301 | "ln -sf /etc/passwd evil && cat evil", 302 | ]); 303 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:338 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L338 336 | 337 | test("argv injection: shell metacharacters not interpreted by execFile", async () => { > 338 | const r = await runIn("/bin/cat", ["hello.txt; cat /etc/passwd"]); 339 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 340 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:446 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L446 444 | } 445 | > 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:448 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L448 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. > 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 449 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 450 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:458 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L458 456 | }); 457 | > 458 | test("blocks ../../etc/passwd traversal from /workspace", async () => { 459 | const r = await runIn("/bin/sh", [ 460 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:461 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L461 459 | const r = await runIn("/bin/sh", [ 460 | "-c", > 461 | "cd /workspace && cat ../../etc/passwd", 462 | ]); 463 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:467 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L467 465 | 466 | test("blocks symlink escape from workspace", async () => { > 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); 469 | // The symlink target /etc/passwd doesn't exist inside the namespace.

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:469 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L469 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); > 469 | // The symlink target /etc/passwd doesn't exist inside the namespace. 470 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 471 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:533 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/__tests__/exec-sandbox.test.ts#L533 531 | test("argv injection: shell metacharacters in execFile args don't escape", async () => { 532 | const r = await runIn("/bin/cat", [ > 533 | "/workspace/hello.txt; cat /etc/passwd", 534 | ]); 535 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/shared/tool-implementations.ts:232 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/a628d2a9b368a2f5bdafc5e574b80901b9f537e4/src/shared/tool-implementations.ts#L232 230 | // Containment check: resolve the real path (following any symlinks) and 231 | // ensure it stays inside the worker's workspace. Without this, an agent > 232 | // can hand us `../../etc/passwd` (or a symlink that points there) and we 233 | // would happily upload it to the user. 234 | let filePath: string;

LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v9.1.0

17 findings
HIGH etc-passwd-access: src/__tests__/embedded-just-bash-bootstrap.test.ts:56 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/embedded-just-bash-bootstrap.test.ts#L56 54 | const ops = await createEmbeddedBashOps({ workspaceDir: workspace }); 55 | const chunks: string[] = []; > 56 | const result = await ops.exec("hostcat /etc/passwd", "/", { 57 | onData: (chunk) => chunks.push(chunk.toString()), 58 | timeout: 5,

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:283 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L283 281 | } 282 | > 283 | test("blocks /etc/passwd", async () => { 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:284 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L284 282 | 283 | test("blocks /etc/passwd", async () => { > 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 286 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:293 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L293 291 | }); 292 | > 293 | test("blocks ../../etc/passwd traversal", async () => { 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:294 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L294 292 | 293 | test("blocks ../../etc/passwd traversal", async () => { > 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 296 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:298 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L298 296 | }); 297 | > 298 | test("blocks symlink-to-/etc/passwd", async () => { 299 | const r = await runIn("/bin/sh", [ 300 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:301 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L301 299 | const r = await runIn("/bin/sh", [ 300 | "-c", > 301 | "ln -sf /etc/passwd evil && cat evil", 302 | ]); 303 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:338 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L338 336 | 337 | test("argv injection: shell metacharacters not interpreted by execFile", async () => { > 338 | const r = await runIn("/bin/cat", ["hello.txt; cat /etc/passwd"]); 339 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 340 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:446 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L446 444 | } 445 | > 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:448 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L448 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. > 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 449 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 450 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:458 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L458 456 | }); 457 | > 458 | test("blocks ../../etc/passwd traversal from /workspace", async () => { 459 | const r = await runIn("/bin/sh", [ 460 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:461 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L461 459 | const r = await runIn("/bin/sh", [ 460 | "-c", > 461 | "cd /workspace && cat ../../etc/passwd", 462 | ]); 463 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:467 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L467 465 | 466 | test("blocks symlink escape from workspace", async () => { > 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); 469 | // The symlink target /etc/passwd doesn't exist inside the namespace.

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:469 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L469 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); > 469 | // The symlink target /etc/passwd doesn't exist inside the namespace. 470 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 471 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:533 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/__tests__/exec-sandbox.test.ts#L533 531 | test("argv injection: shell metacharacters in execFile args don't escape", async () => { 532 | const r = await runIn("/bin/cat", [ > 533 | "/workspace/hello.txt; cat /etc/passwd", 534 | ]); 535 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/shared/tool-implementations.ts:232 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/84430a13971a6622d474fb497747b66c4ef1f30c/src/shared/tool-implementations.ts#L232 230 | // Containment check: resolve the real path (following any symlinks) and 231 | // ensure it stays inside the worker's workspace. Without this, an agent > 232 | // can hand us `../../etc/passwd` (or a symlink that points there) and we 233 | // would happily upload it to the user. 234 | let filePath: string;

LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v9.0.0

17 findings
HIGH etc-passwd-access: src/__tests__/embedded-just-bash-bootstrap.test.ts:56 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/embedded-just-bash-bootstrap.test.ts#L56 54 | const ops = await createEmbeddedBashOps({ workspaceDir: workspace }); 55 | const chunks: string[] = []; > 56 | const result = await ops.exec("hostcat /etc/passwd", "/", { 57 | onData: (chunk) => chunks.push(chunk.toString()), 58 | timeout: 5,

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:283 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L283 281 | } 282 | > 283 | test("blocks /etc/passwd", async () => { 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:284 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L284 282 | 283 | test("blocks /etc/passwd", async () => { > 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 286 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:293 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L293 291 | }); 292 | > 293 | test("blocks ../../etc/passwd traversal", async () => { 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:294 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L294 292 | 293 | test("blocks ../../etc/passwd traversal", async () => { > 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 296 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:298 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L298 296 | }); 297 | > 298 | test("blocks symlink-to-/etc/passwd", async () => { 299 | const r = await runIn("/bin/sh", [ 300 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:301 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L301 299 | const r = await runIn("/bin/sh", [ 300 | "-c", > 301 | "ln -sf /etc/passwd evil && cat evil", 302 | ]); 303 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:338 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L338 336 | 337 | test("argv injection: shell metacharacters not interpreted by execFile", async () => { > 338 | const r = await runIn("/bin/cat", ["hello.txt; cat /etc/passwd"]); 339 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 340 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:446 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L446 444 | } 445 | > 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:448 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L448 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. > 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 449 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 450 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:458 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L458 456 | }); 457 | > 458 | test("blocks ../../etc/passwd traversal from /workspace", async () => { 459 | const r = await runIn("/bin/sh", [ 460 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:461 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L461 459 | const r = await runIn("/bin/sh", [ 460 | "-c", > 461 | "cd /workspace && cat ../../etc/passwd", 462 | ]); 463 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:467 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L467 465 | 466 | test("blocks symlink escape from workspace", async () => { > 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); 469 | // The symlink target /etc/passwd doesn't exist inside the namespace.

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:469 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L469 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); > 469 | // The symlink target /etc/passwd doesn't exist inside the namespace. 470 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 471 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:533 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/__tests__/exec-sandbox.test.ts#L533 531 | test("argv injection: shell metacharacters in execFile args don't escape", async () => { 532 | const r = await runIn("/bin/cat", [ > 533 | "/workspace/hello.txt; cat /etc/passwd", 534 | ]); 535 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/shared/tool-implementations.ts:232 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bf9c0114726954ebf81bec8b630d96737fc5aede/src/shared/tool-implementations.ts#L232 230 | // Containment check: resolve the real path (following any symlinks) and 231 | // ensure it stays inside the worker's workspace. Without this, an agent > 232 | // can hand us `../../etc/passwd` (or a symlink that points there) and we 233 | // would happily upload it to the user. 234 | let filePath: string;

LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v8.0.0

17 findings
HIGH etc-passwd-access: src/__tests__/embedded-just-bash-bootstrap.test.ts:56 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/embedded-just-bash-bootstrap.test.ts#L56 54 | const ops = await createEmbeddedBashOps({ workspaceDir: workspace }); 55 | const chunks: string[] = []; > 56 | const result = await ops.exec("hostcat /etc/passwd", "/", { 57 | onData: (chunk) => chunks.push(chunk.toString()), 58 | timeout: 5,

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:283 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L283 281 | } 282 | > 283 | test("blocks /etc/passwd", async () => { 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:284 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L284 282 | 283 | test("blocks /etc/passwd", async () => { > 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 286 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:293 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L293 291 | }); 292 | > 293 | test("blocks ../../etc/passwd traversal", async () => { 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:294 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L294 292 | 293 | test("blocks ../../etc/passwd traversal", async () => { > 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 296 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:298 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L298 296 | }); 297 | > 298 | test("blocks symlink-to-/etc/passwd", async () => { 299 | const r = await runIn("/bin/sh", [ 300 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:301 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L301 299 | const r = await runIn("/bin/sh", [ 300 | "-c", > 301 | "ln -sf /etc/passwd evil && cat evil", 302 | ]); 303 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:338 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L338 336 | 337 | test("argv injection: shell metacharacters not interpreted by execFile", async () => { > 338 | const r = await runIn("/bin/cat", ["hello.txt; cat /etc/passwd"]); 339 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 340 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:446 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L446 444 | } 445 | > 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:448 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L448 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. > 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 449 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 450 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:458 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L458 456 | }); 457 | > 458 | test("blocks ../../etc/passwd traversal from /workspace", async () => { 459 | const r = await runIn("/bin/sh", [ 460 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:461 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L461 459 | const r = await runIn("/bin/sh", [ 460 | "-c", > 461 | "cd /workspace && cat ../../etc/passwd", 462 | ]); 463 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:467 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L467 465 | 466 | test("blocks symlink escape from workspace", async () => { > 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); 469 | // The symlink target /etc/passwd doesn't exist inside the namespace.

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:469 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L469 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); > 469 | // The symlink target /etc/passwd doesn't exist inside the namespace. 470 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 471 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:533 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/__tests__/exec-sandbox.test.ts#L533 531 | test("argv injection: shell metacharacters in execFile args don't escape", async () => { 532 | const r = await runIn("/bin/cat", [ > 533 | "/workspace/hello.txt; cat /etc/passwd", 534 | ]); 535 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/shared/tool-implementations.ts:232 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/94d9c58edb4124c3a7e817642215b55672ca1966/src/shared/tool-implementations.ts#L232 230 | // Containment check: resolve the real path (following any symlinks) and 231 | // ensure it stays inside the worker's workspace. Without this, an agent > 232 | // can hand us `../../etc/passwd` (or a symlink that points there) and we 233 | // would happily upload it to the user. 234 | let filePath: string;

LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v7.2.0

17 findings
HIGH etc-passwd-access: src/__tests__/embedded-just-bash-bootstrap.test.ts:56 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/embedded-just-bash-bootstrap.test.ts#L56 54 | const ops = await createEmbeddedBashOps({ workspaceDir: workspace }); 55 | const chunks: string[] = []; > 56 | const result = await ops.exec("hostcat /etc/passwd", "/", { 57 | onData: (chunk) => chunks.push(chunk.toString()), 58 | timeout: 5,

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:283 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L283 281 | } 282 | > 283 | test("blocks /etc/passwd", async () => { 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:284 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L284 282 | 283 | test("blocks /etc/passwd", async () => { > 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 286 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:293 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L293 291 | }); 292 | > 293 | test("blocks ../../etc/passwd traversal", async () => { 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:294 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L294 292 | 293 | test("blocks ../../etc/passwd traversal", async () => { > 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 296 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:298 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L298 296 | }); 297 | > 298 | test("blocks symlink-to-/etc/passwd", async () => { 299 | const r = await runIn("/bin/sh", [ 300 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:301 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L301 299 | const r = await runIn("/bin/sh", [ 300 | "-c", > 301 | "ln -sf /etc/passwd evil && cat evil", 302 | ]); 303 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:338 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L338 336 | 337 | test("argv injection: shell metacharacters not interpreted by execFile", async () => { > 338 | const r = await runIn("/bin/cat", ["hello.txt; cat /etc/passwd"]); 339 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 340 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:446 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L446 444 | } 445 | > 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:448 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L448 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. > 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 449 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 450 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:458 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L458 456 | }); 457 | > 458 | test("blocks ../../etc/passwd traversal from /workspace", async () => { 459 | const r = await runIn("/bin/sh", [ 460 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:461 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L461 459 | const r = await runIn("/bin/sh", [ 460 | "-c", > 461 | "cd /workspace && cat ../../etc/passwd", 462 | ]); 463 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:467 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L467 465 | 466 | test("blocks symlink escape from workspace", async () => { > 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); 469 | // The symlink target /etc/passwd doesn't exist inside the namespace.

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:469 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L469 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); > 469 | // The symlink target /etc/passwd doesn't exist inside the namespace. 470 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 471 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:533 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/__tests__/exec-sandbox.test.ts#L533 531 | test("argv injection: shell metacharacters in execFile args don't escape", async () => { 532 | const r = await runIn("/bin/cat", [ > 533 | "/workspace/hello.txt; cat /etc/passwd", 534 | ]); 535 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/shared/tool-implementations.ts:232 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/daa209438132e955a730f4800ef6a4380a426d28/src/shared/tool-implementations.ts#L232 230 | // Containment check: resolve the real path (following any symlinks) and 231 | // ensure it stays inside the worker's workspace. Without this, an agent > 232 | // can hand us `../../etc/passwd` (or a symlink that points there) and we 233 | // would happily upload it to the user. 234 | let filePath: string;

LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v7.1.0

17 findings
HIGH etc-passwd-access: src/__tests__/embedded-just-bash-bootstrap.test.ts:56 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/embedded-just-bash-bootstrap.test.ts#L56 54 | const ops = await createEmbeddedBashOps({ workspaceDir: workspace }); 55 | const chunks: string[] = []; > 56 | const result = await ops.exec("hostcat /etc/passwd", "/", { 57 | onData: (chunk) => chunks.push(chunk.toString()), 58 | timeout: 5,

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:283 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L283 281 | } 282 | > 283 | test("blocks /etc/passwd", async () => { 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:284 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L284 282 | 283 | test("blocks /etc/passwd", async () => { > 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 286 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:293 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L293 291 | }); 292 | > 293 | test("blocks ../../etc/passwd traversal", async () => { 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:294 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L294 292 | 293 | test("blocks ../../etc/passwd traversal", async () => { > 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 296 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:298 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L298 296 | }); 297 | > 298 | test("blocks symlink-to-/etc/passwd", async () => { 299 | const r = await runIn("/bin/sh", [ 300 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:301 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L301 299 | const r = await runIn("/bin/sh", [ 300 | "-c", > 301 | "ln -sf /etc/passwd evil && cat evil", 302 | ]); 303 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:338 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L338 336 | 337 | test("argv injection: shell metacharacters not interpreted by execFile", async () => { > 338 | const r = await runIn("/bin/cat", ["hello.txt; cat /etc/passwd"]); 339 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 340 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:446 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L446 444 | } 445 | > 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:448 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L448 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. > 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 449 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 450 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:458 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L458 456 | }); 457 | > 458 | test("blocks ../../etc/passwd traversal from /workspace", async () => { 459 | const r = await runIn("/bin/sh", [ 460 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:461 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L461 459 | const r = await runIn("/bin/sh", [ 460 | "-c", > 461 | "cd /workspace && cat ../../etc/passwd", 462 | ]); 463 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:467 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L467 465 | 466 | test("blocks symlink escape from workspace", async () => { > 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); 469 | // The symlink target /etc/passwd doesn't exist inside the namespace.

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:469 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L469 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); > 469 | // The symlink target /etc/passwd doesn't exist inside the namespace. 470 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 471 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:533 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/__tests__/exec-sandbox.test.ts#L533 531 | test("argv injection: shell metacharacters in execFile args don't escape", async () => { 532 | const r = await runIn("/bin/cat", [ > 533 | "/workspace/hello.txt; cat /etc/passwd", 534 | ]); 535 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/shared/tool-implementations.ts:232 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/bd3001e4f868fc3ea2aac94084b2c90576ce690e/src/shared/tool-implementations.ts#L232 230 | // Containment check: resolve the real path (following any symlinks) and 231 | // ensure it stays inside the worker's workspace. Without this, an agent > 232 | // can hand us `../../etc/passwd` (or a symlink that points there) and we 233 | // would happily upload it to the user. 234 | let filePath: string;

LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v7.0.0

18 findings
HIGH etc-passwd-access: src/__tests__/embedded-just-bash-bootstrap.test.ts:56 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/embedded-just-bash-bootstrap.test.ts#L56 54 | const ops = await createEmbeddedBashOps({ workspaceDir: workspace }); 55 | const chunks: string[] = []; > 56 | const result = await ops.exec("hostcat /etc/passwd", "/", { 57 | onData: (chunk) => chunks.push(chunk.toString()), 58 | timeout: 5,

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:283 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L283 281 | } 282 | > 283 | test("blocks /etc/passwd", async () => { 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:284 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L284 282 | 283 | test("blocks /etc/passwd", async () => { > 284 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 285 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 286 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:293 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L293 291 | }); 292 | > 293 | test("blocks ../../etc/passwd traversal", async () => { 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:294 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L294 292 | 293 | test("blocks ../../etc/passwd traversal", async () => { > 294 | const r = await runIn("/bin/sh", ["-c", "cat ../../etc/passwd"]); 295 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 296 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:298 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L298 296 | }); 297 | > 298 | test("blocks symlink-to-/etc/passwd", async () => { 299 | const r = await runIn("/bin/sh", [ 300 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:301 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L301 299 | const r = await runIn("/bin/sh", [ 300 | "-c", > 301 | "ln -sf /etc/passwd evil && cat evil", 302 | ]); 303 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:338 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L338 336 | 337 | test("argv injection: shell metacharacters not interpreted by execFile", async () => { > 338 | const r = await runIn("/bin/cat", ["hello.txt; cat /etc/passwd"]); 339 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 340 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:446 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L446 444 | } 445 | > 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:448 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L448 446 | test("blocks /etc/passwd outside the bind", async () => { 447 | // /etc is not bound, so the path doesn't exist inside the namespace at all. > 448 | const r = await runIn("/bin/cat", ["/etc/passwd"]); 449 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 450 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:458 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L458 456 | }); 457 | > 458 | test("blocks ../../etc/passwd traversal from /workspace", async () => { 459 | const r = await runIn("/bin/sh", [ 460 | "-c",

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:461 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L461 459 | const r = await runIn("/bin/sh", [ 460 | "-c", > 461 | "cd /workspace && cat ../../etc/passwd", 462 | ]); 463 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:467 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L467 465 | 466 | test("blocks symlink escape from workspace", async () => { > 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); 469 | // The symlink target /etc/passwd doesn't exist inside the namespace.

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:469 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L469 467 | fs.symlinkSync("/etc/passwd", path.join(workspace, "evil")); 468 | const r = await runIn("/bin/sh", ["-c", "cat /workspace/evil"]); > 469 | // The symlink target /etc/passwd doesn't exist inside the namespace. 470 | expect(r.ok && r.stdout.includes("root:")).toBe(false); 471 | });

HIGH etc-passwd-access: src/__tests__/exec-sandbox.test.ts:533 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/__tests__/exec-sandbox.test.ts#L533 531 | test("argv injection: shell metacharacters in execFile args don't escape", async () => { 532 | const r = await runIn("/bin/cat", [ > 533 | "/workspace/hello.txt; cat /etc/passwd", 534 | ]); 535 | expect(r.ok && r.stdout.includes("root:")).toBe(false);

HIGH env-spread: src/gateway/sse-client.ts:582 semgrep

Spreading entire process.env into an object — may capture all secrets Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/gateway/sse-client.ts#L582 580 | const proc = spawn("sh", ["-c", execCommand], { 581 | cwd: workingDir, > 582 | env: { ...process.env, ...execEnv }, 583 | stdio: ["ignore", "pipe", "pipe"], 584 | });

HIGH etc-passwd-access: src/shared/tool-implementations.ts:232 semgrep

Accessing /etc/passwd or /etc/shadow — credential harvesting on Linux Source: https://github.com/lobu-ai/lobu/blob/597d8da67c3f94f37b9b2d68d90811878788eb19/src/shared/tool-implementations.ts#L232 230 | // Containment check: resolve the real path (following any symlinks) and 231 | // ensure it stays inside the worker's workspace. Without this, an agent > 232 | // can hand us `../../etc/passwd` (or a symlink that points there) and we 233 | // would happily upload it to the user. 234 | let filePath: string;

LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v6.1.1

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v6.0.0

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Consider requesting the maintainer enable provenance via CI/CD.

v4.2.0

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Only ~12% of npm packages have provenance, so this is common but not ideal.

v3.4.1

1 finding
INFO Has SLSA provenance attestation provenance

Published via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.

v3.2.0

1 finding
INFO Has SLSA provenance attestation provenance

Published via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.

v3.0.8

3 findings
HIGH env-spread: src/embedded/just-bash-bootstrap.ts:100 semgrep

Spreading entire process.env into an object — may capture all secrets Source: https://github.com/lobu-ai/lobu/blob/606a82ba9d7879a0a028fb63d1ab09e7e3f6326c/src/embedded/just-bash-bootstrap.ts#L100 98 | 99 | // Convert ctx.env (Map-like) to a plain Record for child_process > 100 | const envRecord: Record<string, string> = { ...process.env } as Record< 101 | string, 102 | string

HIGH env-spread: src/gateway/sse-client.ts:581 semgrep

Spreading entire process.env into an object — may capture all secrets Source: https://github.com/lobu-ai/lobu/blob/606a82ba9d7879a0a028fb63d1ab09e7e3f6326c/src/gateway/sse-client.ts#L581 579 | const proc = spawn("sh", ["-c", execCommand], { 580 | cwd: workingDir, > 581 | env: { ...process.env, ...execEnv }, 582 | stdio: ["ignore", "pipe", "pipe"], 583 | });

LOW No provenance attestation provenance

Package was published without Sigstore provenance. Only ~12% of npm packages have provenance, so this is common but not ideal.

v3.0.7

3 findings
HIGH env-spread: src/embedded/just-bash-bootstrap.ts:100 semgrep

Spreading entire process.env into an object — may capture all secrets Source: https://github.com/lobu-ai/lobu/blob/35af3938f5c7c311ab510ae13066a93034c0fe71/src/embedded/just-bash-bootstrap.ts#L100 98 | 99 | // Convert ctx.env (Map-like) to a plain Record for child_process > 100 | const envRecord: Record<string, string> = { ...process.env } as Record< 101 | string, 102 | string

HIGH env-spread: src/gateway/sse-client.ts:581 semgrep

Spreading entire process.env into an object — may capture all secrets Source: https://github.com/lobu-ai/lobu/blob/35af3938f5c7c311ab510ae13066a93034c0fe71/src/gateway/sse-client.ts#L581 579 | const proc = spawn("sh", ["-c", execCommand], { 580 | cwd: workingDir, > 581 | env: { ...process.env, ...execEnv }, 582 | stdio: ["ignore", "pipe", "pipe"], 583 | });

LOW No provenance attestation provenance

Package was published without Sigstore provenance. Only ~12% of npm packages have provenance, so this is common but not ideal.

v2.8.0

1 finding
LOW No provenance attestation provenance

Package was published without Sigstore provenance. Only ~12% of npm packages have provenance, so this is common but not ideal.