{"record":{"id":"556686266ce48242","repo":"multica-ai/multica","slug":"command-name-cannot-contain-nul-bytes","errorCode":null,"errorMessage":"command_name cannot contain NUL bytes","messagePattern":"command_name cannot contain NUL bytes","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/internal/handler/runtime_profile.go","lineNumber":111,"sourceCode":"\t\t\treturn nil, errors.New(\"fixed_args entries must be non-empty\")\n\t\t}\n\t\tif strings.ContainsRune(a, '\\x00') {\n\t\t\treturn nil, errors.New(\"fixed_args entries cannot contain NUL bytes\")\n\t\t}\n\t\tclean = append(clean, a)\n\t}\n\treturn json.Marshal(clean)\n}\n\nfunc validateRuntimeProfileCommandName(commandName string) error {\n\tif commandName == \"\" {\n\t\treturn errors.New(\"command_name is required\")\n\t}\n\tif strings.ContainsAny(commandName, \" \\t\\r\\n\") {\n\t\treturn errors.New(\"command_name must be a single executable token; put arguments in fixed_args\")\n\t}\n\tif strings.ContainsRune(commandName, '\\x00') {\n\t\treturn errors.New(\"command_name cannot contain NUL bytes\")\n\t}\n\treturn nil\n}\n\ntype createRuntimeProfileRequest struct {\n\tDisplayName    string   `json:\"display_name\"`\n\tProtocolFamily string   `json:\"protocol_family\"`\n\tCommandName    string   `json:\"command_name\"`\n\tDescription    *string  `json:\"description\"`\n\tFixedArgs      []string `json:\"fixed_args\"`\n\tEnabled        *bool    `json:\"enabled\"`\n}\n\n// CreateRuntimeProfile creates a workspace runtime profile. Admin-gated by the\n// router. protocol_family is validated against the agent backend whitelist.\nfunc (h *Handler) CreateRuntimeProfile(w http.ResponseWriter, r *http.Request) {\n\twsID := strings.TrimSpace(chi.URLParam(r, \"id\"))\n\tmember, ok := h.requireWorkspaceMember(w, r, wsID, \"workspace not found\")","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/handler/runtime_profile.go#L93-L129","documentation":"validateRuntimeProfileCommandName rejects command_name values containing a NUL byte. Same rationale as the fixed_args NUL check: Go strings carry NUL fine, but exec argv cannot, so a NUL would truncate the executable path at spawn time. Failing at validation surfaces the corruption immediately.","triggerScenarios":"POST/PUT a runtime profile whose command_name contains \\u0000 — binary-corrupted input, fuzzed payloads, or a buffer decoded with the wrong encoding.","commonSituations":"Command read from a binary protocol or fixed-width record padded with NULs; encoding bugs (UTF-32 decoded as bytes); penetration-test payloads probing argv injection.","solutions":["Strip NULs and control characters from the command string before sending","Validate input is printable UTF-8 at the client boundary","Treat NUL in this field as a bug in the producer — find and fix the source of the binary data"],"exampleFix":"// before\ncommandName: buf.toString(\"utf8\")\n// after\ncommandName: buf.toString(\"utf8\").replace(/[\\x00\\r\\n]/g, \"\").trim()","handlingStrategy":"validation","validationCode":"if (commandName.includes('\\x00')) {\n  throw new Error('Corrupt input: NUL byte in executable name');\n}","typeGuard":"function isNulFreeCommand(s: string): boolean { return !s.includes('\\x00'); }","tryCatchPattern":null,"preventionTips":["Decode binary sources explicitly and validate as text","Sanitize control characters at the client boundary","Treat NUL here as a security signal — log and investigate, don't just strip"],"tags":["validation","runtime-profile","nul-byte","security"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}