Conversation
…s, and UI wizard Add 12 stages of functionality including: - Stage 9/17: Enhanced 8-step wizard UI with SeverityBadge, DiffViewer, TreePreview, FindingsFilter components and deeper page integration - Stage 10: History preservation prerequisites and dry-run reporting - Stage 11: Full lifecycle CLI commands (add, archive, migrate-branch) with plan types - Stage 12: Extended analysis (environment, tooling, CI, publishing, repo risks) with risk classification - Stage 13: Path-filtered GitHub Actions workflow generation - Stage 14: Configure engine for Prettier/ESLint/TypeScript scaffolding - Stage 15: Dependency enforcement via overrides/resolutions - Stage 16: Cross-platform path normalization - Stage 18: Smart defaults with evidence-based suggestions and error shaping - Stage 19: Multi-language detection and scaffolding (Go, Rust, Python) - Stage 20: Performance utilities (pMap concurrency, disk space check, progress emitter) 674 unit tests passing across 49 test files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
||
| // Fetch | ||
| logger.info(`Fetching ${branch}...`); | ||
| await safeExecFile('git', ['fetch', remoteName, branch], { |
Check failure
Code scanning / CodeQL
Second order command injection High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 month ago
In general: to fix this issue, we must validate and constrain user-controlled values before they reach git. For branch, that means only permitting branch-like names (e.g., alphanumerics plus a small set of punctuation such as /, -, _, ., limiting length, and rejecting values that start with - or contain whitespace or globbing characters). Similarly, we should restrict subdir (coming from options.subdir or defaulting to plan.sourceRepo) to a safe relative path pattern and disallow .., absolute paths, or path separators that could escape the repo. sourceRepo and targetMonorepo appear to be local filesystem paths; these are used as cwd and remote URL for git remote add, so at minimum we should ensure they are strings and non-empty, but the second-order injection highlighted by CodeQL is primarily about the branch argument.
Best single fix without changing existing behavior: add explicit validation helpers in src/server/routes/migrate-branch.ts and apply them to branch and options.subdir before we ever call generateBranchPlan/applyBranchPlan. This keeps all logic at the HTTP boundary and avoids modifying the strategy logic. Concretely:
- In
src/server/routes/migrate-branch.ts, define:isValidBranchName(name: string): booleanusing a conservative regex (e.g.,/^[A-Za-z0-9][A-Za-z0-9._/-]{0,254}$/) and additional checks like “not starting with-” and no consecutive..to keep it simple and safe.isValidSubdir(subdir: string): booleanthat ensures it’s a relative directory name without.., without starting with/or\, and containing only safe characters likeA-Za-z0-9._/-.
- In the POST handler:
- After checking
branchis a string, callisValidBranchName(branch); if it fails, return HTTP 400 with a clear error. - If
options?.subdiris provided, check it is a string and passesisValidSubdir; otherwise return 400.
- After checking
- Then pass
branchandoptions.subdiras before. Because we are only rejecting obviously unsafe names and not transforming values, normal use (with typical git-style branch names) will continue to work.
No changes to imports are strictly required (we can implement these helpers inline). We do not need to alter src/strategies/migrate-branch.ts for this fix; validating at the route layer is sufficient to break the tainted flow.
| // Use wmic on Windows | ||
| const drive = path.parse(path.resolve(dirPath)).root; | ||
| const { stdout } = await execFileAsync('wmic', [ | ||
| 'logicaldisk', 'where', `DeviceID='${drive.replace('\\', '')}'`, |
Check failure
Code scanning / CodeQL
Incomplete string escaping or encoding High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 month ago
In general, when sanitizing strings by removing or escaping certain characters, use a global regular expression (/pattern/g) so that all occurrences are handled, not just the first. For backslash removal, this means using .replace(/\\/g, '') instead of .replace('\\', '').
For this specific code in src/utils/disk.ts, update the construction of the DeviceID filter on line 18 so that all backslashes are removed from drive. Change:
`DeviceID='${drive.replace('\\', '')}'`,to:
`DeviceID='${drive.replace(/\\/g, '')}'`,This preserves the intended functionality—turning "C:\\" into "C:"—while correctly handling any unexpected extra backslashes in drive. No new imports or auxiliary methods are needed; this is a localized change within the existing function.
| @@ -15,7 +15,7 @@ | ||
| // Use wmic on Windows | ||
| const drive = path.parse(path.resolve(dirPath)).root; | ||
| const { stdout } = await execFileAsync('wmic', [ | ||
| 'logicaldisk', 'where', `DeviceID='${drive.replace('\\', '')}'`, | ||
| 'logicaldisk', 'where', `DeviceID='${drive.replace(/\\/g, '')}'`, | ||
| 'get', 'FreeSpace', '/format:value', | ||
| ]); | ||
| const match = stdout.match(/FreeSpace=(\d+)/); |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ckers SEC-01: Sanitize Python injection in history-preserve commitPrefix SEC-02: Add path traversal prevention in apply command SEC-03: Add Bearer token auth to server API and WebSocket SEC-04: Allowlist install command executables in apply SEC-05: Replace shell exec() with execFile() in ui command SEC-06: Cap concurrent operations and event buffer in WsHub Publishing: rename to monotize, add LICENSE/SECURITY.md/CHANGELOG.md, add files field, author, repository metadata, semver and js-yaml deps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
add,archive,migrate-branch) with typed plan artifacts (AddPlan, ArchivePlan, BranchPlan)Test plan
tsc --noEmit) passes cleanlynode bin/monorepo.js --helpshows all commandsnode bin/monorepo.js uiserves working wizard🤖 Generated with Claude Code