Skip to content

Commit 15e4715

Browse files
la14-1louisgvclaude
authored
fix: validate server ID in status.ts before API calls (#2430)
status.ts passed server_id from history directly into Hetzner/DO API URLs without calling validateServerIdentifier(). Both delete.ts and connect.ts validate first; status.ts was the only gap. A tampered ~/.spawn/history.json could craft a server_id with path traversal characters (e.g. "../v2/account") causing the Bearer token to be sent to an unintended API endpoint (SSRF via URL path manipulation). Fix: call validateServerIdentifier() after extracting serverId, returning "unknown" gracefully on failure. Agent: code-health Co-authored-by: B <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 00aa4b2 commit 15e4715

2 files changed

Lines changed: 7 additions & 1 deletion

File tree

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openrouter/spawn",
3-
"version": "0.15.36",
3+
"version": "0.15.37",
44
"type": "module",
55
"bin": {
66
"spawn": "cli.js"

packages/cli/src/commands/status.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as p from "@clack/prompts";
55
import pc from "picocolors";
66
import { filterHistory, markRecordDeleted } from "../history.js";
77
import { loadManifest } from "../manifest.js";
8+
import { validateServerIdentifier } from "../security.js";
89
import { parseJsonObj } from "../shared/parse.js";
910
import { isString, toRecord } from "../shared/type-guards.js";
1011
import { loadApiToken } from "../shared/ui.js";
@@ -115,6 +116,11 @@ async function checkServerStatus(record: SpawnRecord): Promise<LiveState> {
115116
if (!serverId) {
116117
return "unknown";
117118
}
119+
try {
120+
validateServerIdentifier(serverId);
121+
} catch {
122+
return "unknown";
123+
}
118124

119125
switch (conn.cloud) {
120126
case "hetzner": {

0 commit comments

Comments
 (0)