{"record":{"id":"a5f36d0a4da18ae6","repo":"ruvnet/ruflo","slug":"basepath-contains-disallowed-characters","errorCode":null,"errorMessage":"basePath contains disallowed characters","messagePattern":"basePath contains disallowed characters","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/mcp-tools/agentbbs-tools.ts","lineNumber":64,"sourceCode":"  } catch (err: any) {\n    if (err && (err.code === 'ERR_MODULE_NOT_FOUND' || err.code === 'MODULE_NOT_FOUND' ||\n                /Cannot find (module|package)/i.test(String(err?.message)))) {\n      _agentbbsMod = false;\n      return null;\n    }\n    throw err;\n  }\n}\n\nfunction degradedResult(reason: string): { success: true; degraded: true; reason: string } {\n  return { success: true, degraded: true, reason };\n}\n\nfunction resolveBasePath(input?: string): string {\n  const p = input && typeof input === 'string' && input.length > 0\n    ? input\n    : '.agentbbs';\n  if (/\\.\\.[\\\\/]|\\0/.test(p)) throw new Error('basePath contains disallowed characters');\n  const abs = isAbsolute(p) ? p : resolve(getProjectCwd(), p);\n  return abs;\n}\n\nfunction validateRoomLabel(label: string): string {\n  if (!label || typeof label !== 'string') throw new Error('roomLabel is required');\n  if (label.length > 128) throw new Error('roomLabel exceeds 128 chars');\n  // Rooms are conventionally `#sales`, `#finance`, etc. — keep `#` in the allow-list.\n  if (!/^[A-Za-z0-9_.\\-:/@#]+$/.test(label)) {\n    throw new Error('roomLabel may only contain [A-Za-z0-9_.\\\\-:/@#]');\n  }\n  return label;\n}\n\nfunction validateRoomId(roomId: string): string {\n  if (!roomId || typeof roomId !== 'string') throw new Error('roomId is required');\n  if (roomId.length > 128) throw new Error('roomId exceeds 128 chars');\n  if (!/^[A-Za-z0-9_.\\-:/@#]+$/.test(roomId)) {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/mcp-tools/agentbbs-tools.ts#L46-L82","documentation":"Thrown by resolveBasePath() in agentbbs-tools when the user-supplied basePath matches the regex `/\\.\\.[\\\\/]|\\0/` — i.e. it contains a `..` path segment (forward or back slash) or a NUL byte. This is the D-2 path-traversal hardening shared across the MCP verbs: it prevents a caller from escaping the resolved project cwd root. The default `.agentbbs` is always safe.","triggerScenarios":"A tool caller passes `basePath: '../../../tmp'` or `basePath: 'foo/../bar'`; an automated pipeline interpolates an unvalidated env var into basePath; a NUL byte is injected to truncate the path in the underlying syscall.","commonSituations":"User-supplied config value for basePath that was not sanitized; a path built via template string from request data; testing harness that fed a literal traversal string.","solutions":["Pass a simple relative directory name (e.g. `.agentbbs`) or an absolute path inside the project root.","Sanitize upstream: strip `..` segments and NUL bytes before calling the tool, or resolve+verify the result is inside getProjectCwd().","If an absolute path outside the project is genuinely required, host the BBS state there directly (absolute paths are allowed as long as they contain no `..` or NUL), but confirm the operator intends that location."],"exampleFix":"// before — traversal attempt\nfederation_bbs_register({ basePath: '../../etc', roomLabel: '#x' });\n// after\nfederation_bbs_register({ basePath: '.agentbbs', roomLabel: '#x' });","handlingStrategy":"validation","validationCode":"function safeBasePath(p?: string): string {\n  const v = (p && typeof p === 'string' && p.length > 0) ? p : '.agentbbs';\n  if (/\\.\\.[\\\\/]|\\0/.test(v)) throw new Error('basePath would escape project root');\n  return v;\n}\nconst basePath = safeBasePath(input.basePath);","typeGuard":"const isTraversalFree = (p: string): boolean => typeof p === 'string' && !/\\.\\.[\\\\/]|\\0/.test(p);","tryCatchPattern":"null","preventionTips":["Never interpolate untrusted input directly into basePath.","Resolve and verify the absolute path is inside the project root before passing it.","Reject NUL bytes anywhere user data flows into filesystem APIs."],"tags":["security","path-traversal","validation","agentbbs"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}