{"record":{"id":"52c21d6d035c7aad","repo":"ruvnet/ruflo","slug":"label-contains-null-bytes","errorCode":null,"errorMessage":"${label} contains null bytes","messagePattern":"(.+?) contains null bytes","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/commands/daemon.ts","lineNumber":372,"sourceCode":"\n      return { success: true };\n    } catch (error) {\n      output.printError(`Failed to start daemon: ${error instanceof Error ? error.message : String(error)}`);\n      return { success: false, exitCode: 1 };\n    }\n  },\n};\n\n/**\n * Validate path for security - prevents path traversal and injection\n */\nfunction validatePath(path: string, label: string): void {\n  // Must be absolute after resolution\n  const resolved = resolve(path);\n\n  // Check for null bytes (injection attack)\n  if (path.includes('\\0')) {\n    throw new Error(`${label} contains null bytes`);\n  }\n\n  // Check for shell metacharacters in path components\n  if (/[;&|`$<>]/.test(path)) {\n    throw new Error(`${label} contains shell metacharacters`);\n  }\n\n  // Prevent path traversal outside expected directories\n  if (!resolved.includes('.claude-flow') && !resolved.includes('bin')) {\n    // Allow only paths within project structure\n    const cwd = process.cwd();\n    if (!resolved.startsWith(cwd)) {\n      throw new Error(`${label} escapes project directory`);\n    }\n  }\n}\n\n/**","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/commands/daemon.ts#L354-L390","documentation":"Thrown by the internal validatePath() function in daemon.ts when a path argument contains a null byte (\\0). Null bytes are a classic injection vector — they can truncate strings in C-based path APIs and bypass security filters that check suffixes or prefixes. This is a defence-in-depth security check before the path is used in child-process argv or ps/tasklist comparisons.","triggerScenarios":"Any call path that routes through validatePath() with a string containing the literal null character '\\0'. This includes daemon workspace paths, bin paths, or any label-path pair passed to the validator.","commonSituations":"A malicious or corrupted input contains an embedded null byte; a binary file was accidentally read as a path string; a test fixture included a null byte that leaked into a path argument.","solutions":["Remove all null bytes from the path string before passing it to the daemon","Sanitize input at the system boundary: strip or reject '\\0' characters","If the path comes from a file or environment variable, validate it does not contain null bytes before use"],"exampleFix":"// before\nconst workspace = getUserInput(); // \"proj\\0.evil\"\nvalidatePath(workspace, 'workspace');\n\n// after\nconst workspace = getUserInput().replace(/\\0/g, '');\nvalidatePath(workspace, 'workspace');","handlingStrategy":"validation","validationCode":"function isSafePath(path: string): boolean {\n  return !path.includes('\\0');\n}\n\nif (!isSafePath(userPath)) {\n  throw new Error('Path contains null bytes');\n}","typeGuard":"function isNullByteFree(s: string): boolean {\n  return !s.includes('\\0');\n}","tryCatchPattern":"try {\n  validatePath(userPath, 'workspace');\n} catch (e) {\n  if (e instanceof Error && e.message.includes('null bytes')) {\n    userPath = userPath.replace(/\\0/g, '');\n    // Retry with sanitized path\n  }\n}","preventionTips":["Sanitize all path inputs at system boundaries — strip null bytes early","Never pass binary file contents as path strings","Use resolveWorkspaceFlag() for --workspace values — it already rejects null bytes"],"tags":["security","path-traversal","null-byte","injection","daemon"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}