mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-20 09:31:15 +00:00
fix(security): add cmd validation to Sprite runSprite() and runSpriteSilent() (#2904)
Mirrors the guard already in interactiveSession() and all other clouds. Null bytes in cmd could truncate commands at the C level. Fixes #2903 Agent: security-auditor Co-authored-by: B <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5392ff2d7a
commit
97b6424ebe
2 changed files with 20 additions and 0 deletions
|
|
@ -488,6 +488,20 @@ describe("sprite/destroyServer", () => {
|
|||
});
|
||||
});
|
||||
|
||||
// ─── runSprite validation ────────────────────────────────────────────────────
|
||||
|
||||
describe("sprite/runSprite validation", () => {
|
||||
it("rejects empty command", async () => {
|
||||
const { runSprite } = await import("../sprite/sprite");
|
||||
await expect(runSprite("")).rejects.toThrow("Invalid command");
|
||||
});
|
||||
|
||||
it("rejects null byte in command", async () => {
|
||||
const { runSprite } = await import("../sprite/sprite");
|
||||
await expect(runSprite("echo\x00hello")).rejects.toThrow("Invalid command");
|
||||
});
|
||||
});
|
||||
|
||||
// ─── runSprite ───────────────────────────────────────────────────────────────
|
||||
|
||||
describe("sprite/runSprite", () => {
|
||||
|
|
|
|||
|
|
@ -478,6 +478,9 @@ export function getVmConnection(): VMConnection {
|
|||
* Run a command on the remote sprite. Retries on transient errors.
|
||||
*/
|
||||
export async function runSprite(cmd: string, timeoutSecs?: number): Promise<void> {
|
||||
if (!cmd || /\0/.test(cmd)) {
|
||||
throw new Error("Invalid command: must be non-empty and must not contain null bytes");
|
||||
}
|
||||
const spriteCmd = getSpriteCmd()!;
|
||||
await spriteRetry("sprite exec", async () => {
|
||||
const proc = Bun.spawn(
|
||||
|
|
@ -515,6 +518,9 @@ export async function runSprite(cmd: string, timeoutSecs?: number): Promise<void
|
|||
|
||||
/** Run a command silently (no stdout/stderr). Throws on failure. */
|
||||
async function runSpriteSilent(cmd: string): Promise<void> {
|
||||
if (!cmd || /\0/.test(cmd)) {
|
||||
throw new Error("Invalid command: must be non-empty and must not contain null bytes");
|
||||
}
|
||||
const spriteCmd = getSpriteCmd()!;
|
||||
const proc = Bun.spawn(
|
||||
[
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue