mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-02 20:43:36 +00:00
refactor: implement ALLOWED_ROOT_DIRECTORY security and fix path validation
This commit consolidates directory security from two environment variables (WORKSPACE_DIR, ALLOWED_PROJECT_DIRS) into a single ALLOWED_ROOT_DIRECTORY variable while maintaining backward compatibility. Changes: - Re-enabled path validation in security.ts (was previously disabled) - Implemented isPathAllowed() to check ALLOWED_ROOT_DIRECTORY with DATA_DIR exception - Added backward compatibility for legacy ALLOWED_PROJECT_DIRS and WORKSPACE_DIR - Implemented path traversal protection via isPathWithinDirectory() helper - Added PathNotAllowedError custom exception for security violations - Updated all FS route endpoints to validate paths and return 403 on violation - Updated template clone endpoint to validate project paths - Updated workspace config endpoints to use ALLOWED_ROOT_DIRECTORY - Fixed stat() response property access bug in project-init.ts - Updated security tests to expect actual validation behavior Security improvements: - Path validation now enforced at all layers (routes, project init, agent services) - appData directory (DATA_DIR) always allowed for settings/credentials - Backward compatible with existing ALLOWED_PROJECT_DIRS/WORKSPACE_DIR configurations - Protection against path traversal attacks Backend test results: 654/654 passing ✅ 🤖 Generated with Claude Code Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,7 @@ import { resolveDependencies, areDependenciesSatisfied } from "../lib/dependency
|
||||
import type { Feature } from "./feature-loader.js";
|
||||
import { FeatureLoader } from "./feature-loader.js";
|
||||
import { getFeatureDir, getAutomakerDir, getFeaturesDir, getContextDir } from "../lib/automaker-paths.js";
|
||||
import { isPathAllowed, PathNotAllowedError } from "../lib/security.js";
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
@@ -486,6 +487,11 @@ export class AutoModeService {
|
||||
this.runningFeatures.set(featureId, tempRunningFeature);
|
||||
|
||||
try {
|
||||
// Validate that project path is allowed
|
||||
if (!isPathAllowed(projectPath)) {
|
||||
throw new PathNotAllowedError(projectPath);
|
||||
}
|
||||
|
||||
// Check if feature has existing context - if so, resume instead of starting fresh
|
||||
// Skip this check if we're already being called with a continuation prompt (from resumeFeature)
|
||||
if (!options?.continuationPrompt) {
|
||||
@@ -549,6 +555,11 @@ export class AutoModeService {
|
||||
? path.resolve(worktreePath)
|
||||
: path.resolve(projectPath);
|
||||
|
||||
// Validate that working directory is allowed
|
||||
if (!isPathAllowed(workDir)) {
|
||||
throw new PathNotAllowedError(workDir);
|
||||
}
|
||||
|
||||
// Update running feature with actual worktree info
|
||||
tempRunningFeature.worktreePath = worktreePath;
|
||||
tempRunningFeature.branchName = branchName ?? null;
|
||||
|
||||
Reference in New Issue
Block a user