{"record":{"id":"5318c5fdf8c881ae","repo":"ruvnet/ruflo","slug":"dangerous-key-segment-rejected-part","errorCode":null,"errorMessage":"Dangerous key segment rejected: ${part}","messagePattern":"Dangerous key segment rejected: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/mcp-tools/config-tools.ts","lineNumber":109,"sourceCode":"function filterDangerousKeys(obj: Record<string, unknown>): Record<string, unknown> {\n  const filtered: Record<string, unknown> = {};\n  for (const [key, value] of Object.entries(obj)) {\n    if (!DANGEROUS_KEYS.has(key)) {\n      filtered[key] = value;\n    }\n  }\n  return filtered;\n}\n\nfunction setNestedValue(obj: Record<string, unknown>, key: string, value: unknown): void {\n  const MAX_NESTING_DEPTH = 10;\n  const parts = key.split('.');\n  if (parts.length > MAX_NESTING_DEPTH) {\n    throw new Error(`Key exceeds maximum nesting depth of ${MAX_NESTING_DEPTH}`);\n  }\n  for (const part of parts) {\n    if (DANGEROUS_KEYS.has(part)) {\n      throw new Error(`Dangerous key segment rejected: ${part}`);\n    }\n  }\n  let current = obj;\n  for (let i = 0; i < parts.length - 1; i++) {\n    const part = parts[i];\n    if (!(part in current) || typeof current[part] !== 'object') {\n      current[part] = {};\n    }\n    current = current[part] as Record<string, unknown>;\n  }\n  current[parts[parts.length - 1]] = value;\n}\n\nexport const configTools: MCPTool[] = [\n  {\n    name: 'config_get',\n    description: 'Get configuration value Use when native settings.json edits are wrong because the values need to be read by the Ruflo runtime (daemon, MCP server, neural router) — those load via the config_* path, not by re-reading settings.json. For .gitignore / .editorconfig style files, native Edit is fine.',\n    category: 'config',","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/mcp-tools/config-tools.ts#L91-L127","documentation":"Thrown by setNestedValue() in config-tools.ts:109 when ANY dot-separated segment of a config_set key is in DANGEROUS_KEYS = {'__proto__', 'constructor', 'prototype'}. This is a prototype-pollution guard: those segment names, when used as object keys during nested writes, can hijack Object.prototype in older runtimes or pollute structures downstream. Every segment is checked before any mutation.","triggerScenarios":"config_set with a key like '__proto__.polluted', 'constructor.prototype.x', or any legitimate-looking key that happens to contain a segment named exactly 'constructor', 'prototype', or '__proto__' (e.g. 'ui.widget.prototype.enabled').","commonSituations":"Security scanners and pentests probing the MCP config endpoint; applications that forward arbitrary user-supplied keys to config_set; domain vocabulary ('design.prototype.theme') colliding with the blacklist.","solutions":["Rename the colliding segment ('prototype' -> 'proto', 'base', 'template')","Never forward raw user input as config keys — validate against an allowlist of known keys first","If you did not send the call, treat this error as an attack signal: audit who has access to the config tools"],"exampleFix":"// before\nawait callTool('config_set', { key: '__proto__.polluted', value: true });\n// throws: Dangerous key segment rejected: __proto__\n\n// after (legit deep config: avoid the reserved segment name)\nawait callTool('config_set', { key: 'design.proto.theme', value: 'dark' });","handlingStrategy":"validation","validationCode":"const DANGEROUS = new Set(['__proto__', 'constructor', 'prototype']);\nfunction isSafeConfigKey(key: string): boolean {\n  return key.split('.').every((seg) => seg.length > 0 && !DANGEROUS.has(seg));\n}\nif (!isSafeConfigKey(userKey)) throw new TypeError('config key rejected: reserved segment');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate config keys against an allowlist of known settings instead of accepting arbitrary dotted paths","Treat unexpected triggers of this error as a security signal — audit the caller's access to config_set","Avoid the segment names 'constructor', 'prototype', '__proto__' in your own config vocabulary"],"tags":["security","prototype-pollution","config","validation","mcp"],"backgroundTag":"prototype-pollution-blocked","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}