refactor: integrate secure file system operations across services

This commit replaces direct file system operations with a secure file system adapter to enhance security by enforcing path validation. The changes include:

- Replaced `fs` imports with `secureFs` in various services and utilities.
- Updated file operations in `agent-service`, `auto-mode-service`, `feature-loader`, and `settings-service` to use the secure file system methods.
- Ensured that all file I/O operations are validated against the ALLOWED_ROOT_DIRECTORY.

This refactor aims to prevent unauthorized file access and improve overall security posture.

Tests: All unit tests passing.

🤖 Generated with Claude Code
This commit is contained in:
Test User
2025-12-20 18:45:39 -05:00
parent ade80484bb
commit f3c9e828e2
45 changed files with 329 additions and 551 deletions

View File

@@ -14,6 +14,7 @@
import { Router } from "express";
import type { SettingsService } from "../../services/settings-service.js";
import { validatePathParams } from "../../middleware/validate-paths.js";
import { createGetGlobalHandler } from "./routes/get-global.js";
import { createUpdateGlobalHandler } from "./routes/update-global.js";
import { createGetCredentialsHandler } from "./routes/get-credentials.js";
@@ -57,8 +58,8 @@ export function createSettingsRoutes(settingsService: SettingsService): Router {
router.put("/credentials", createUpdateCredentialsHandler(settingsService));
// Project settings
router.post("/project", createGetProjectHandler(settingsService));
router.put("/project", createUpdateProjectHandler(settingsService));
router.post("/project", validatePathParams("projectPath"), createGetProjectHandler(settingsService));
router.put("/project", validatePathParams("projectPath"), createUpdateProjectHandler(settingsService));
// Migration from localStorage
router.post("/migrate", createMigrateHandler(settingsService));

View File

@@ -11,7 +11,6 @@
import type { Request, Response } from "express";
import type { SettingsService } from "../../../services/settings-service.js";
import { getErrorMessage, logError } from "../common.js";
import { validatePath, PathNotAllowedError } from "../../../lib/security.js";
/**
* Create handler factory for POST /api/settings/project
@@ -32,20 +31,6 @@ export function createGetProjectHandler(settingsService: SettingsService) {
return;
}
// Validate paths are within ALLOWED_ROOT_DIRECTORY
try {
validatePath(projectPath);
} catch (error) {
if (error instanceof PathNotAllowedError) {
res.status(403).json({
success: false,
error: error.message,
});
return;
}
throw error;
}
const settings = await settingsService.getProjectSettings(projectPath);
res.json({

View File

@@ -12,7 +12,6 @@ import type { Request, Response } from "express";
import type { SettingsService } from "../../../services/settings-service.js";
import type { ProjectSettings } from "../../../types/settings.js";
import { getErrorMessage, logError } from "../common.js";
import { validatePath, PathNotAllowedError } from "../../../lib/security.js";
/**
* Create handler factory for PUT /api/settings/project
@@ -44,20 +43,6 @@ export function createUpdateProjectHandler(settingsService: SettingsService) {
return;
}
// Validate paths are within ALLOWED_ROOT_DIRECTORY
try {
validatePath(projectPath);
} catch (error) {
if (error instanceof PathNotAllowedError) {
res.status(403).json({
success: false,
error: error.message,
});
return;
}
throw error;
}
const settings = await settingsService.updateProjectSettings(
projectPath,
updates