mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-02 08:33:36 +00:00
refactor: enhance security and streamline file handling
This commit introduces several improvements to the security and file handling mechanisms across the application. Key changes include: - Updated the Dockerfile to pin the GitHub CLI version for reproducible builds. - Refactored the secure file system operations to ensure consistent path validation and type handling. - Removed legacy path management functions and streamlined the allowed paths logic in the security module. - Enhanced route handlers to validate path parameters against the ALLOWED_ROOT_DIRECTORY, improving security against unauthorized access. - Updated the settings service to focus solely on the Anthropic API key, removing references to Google and OpenAI keys. These changes aim to enhance security, maintainability, and clarity in the codebase. Tests: All unit tests passing.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import fs from "fs/promises";
|
||||
import type { Dirent } from "fs";
|
||||
import path from "path";
|
||||
import { validatePath } from "./security.js";
|
||||
|
||||
@@ -41,7 +42,7 @@ export async function writeFile(
|
||||
encoding?: BufferEncoding
|
||||
): Promise<void> {
|
||||
const validatedPath = validatePath(filePath);
|
||||
return fs.writeFile(validatedPath, data, encoding as any);
|
||||
return fs.writeFile(validatedPath, data, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,12 +59,23 @@ export async function mkdir(
|
||||
/**
|
||||
* Wrapper around fs.readdir that validates path first
|
||||
*/
|
||||
export async function readdir(
|
||||
dirPath: string,
|
||||
options?: { withFileTypes?: false; encoding?: BufferEncoding }
|
||||
): Promise<string[]>;
|
||||
export async function readdir(
|
||||
dirPath: string,
|
||||
options: { withFileTypes: true; encoding?: BufferEncoding }
|
||||
): Promise<Dirent[]>;
|
||||
export async function readdir(
|
||||
dirPath: string,
|
||||
options?: { withFileTypes?: boolean; encoding?: BufferEncoding }
|
||||
): Promise<string[] | any[]> {
|
||||
): Promise<string[] | Dirent[]> {
|
||||
const validatedPath = validatePath(dirPath);
|
||||
return fs.readdir(validatedPath, options as any);
|
||||
if (options?.withFileTypes === true) {
|
||||
return fs.readdir(validatedPath, { withFileTypes: true });
|
||||
}
|
||||
return fs.readdir(validatedPath);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +127,7 @@ export async function appendFile(
|
||||
encoding?: BufferEncoding
|
||||
): Promise<void> {
|
||||
const validatedPath = validatePath(filePath);
|
||||
return fs.appendFile(validatedPath, data, encoding as any);
|
||||
return fs.appendFile(validatedPath, data, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,9 +23,6 @@ let allowedRootDirectory: string | null = null;
|
||||
// Data directory - always allowed for settings/credentials
|
||||
let dataDirectory: string | null = null;
|
||||
|
||||
// Allowed paths set - stores ALLOWED_ROOT_DIRECTORY and DATA_DIR
|
||||
const allowedPaths = new Set<string>();
|
||||
|
||||
/**
|
||||
* Initialize security settings from environment variables
|
||||
* - ALLOWED_ROOT_DIRECTORY: main security boundary
|
||||
@@ -36,7 +33,6 @@ export function initAllowedPaths(): void {
|
||||
const rootDir = process.env.ALLOWED_ROOT_DIRECTORY;
|
||||
if (rootDir) {
|
||||
allowedRootDirectory = path.resolve(rootDir);
|
||||
allowedPaths.add(allowedRootDirectory);
|
||||
console.log(
|
||||
`[Security] ✓ ALLOWED_ROOT_DIRECTORY configured: ${allowedRootDirectory}`
|
||||
);
|
||||
@@ -50,19 +46,10 @@ export function initAllowedPaths(): void {
|
||||
const dataDir = process.env.DATA_DIR;
|
||||
if (dataDir) {
|
||||
dataDirectory = path.resolve(dataDir);
|
||||
allowedPaths.add(dataDirectory);
|
||||
console.log(`[Security] ✓ DATA_DIR configured: ${dataDirectory}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a path to the allowed list
|
||||
* Used when dynamically creating new directories within the allowed root
|
||||
*/
|
||||
export function addAllowedPath(filePath: string): void {
|
||||
allowedPaths.add(path.resolve(filePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a path is allowed based on ALLOWED_ROOT_DIRECTORY
|
||||
* Returns true if:
|
||||
@@ -145,5 +132,12 @@ export function getDataDirectory(): string | null {
|
||||
* Get list of allowed paths (for debugging)
|
||||
*/
|
||||
export function getAllowedPaths(): string[] {
|
||||
return Array.from(allowedPaths);
|
||||
const paths: string[] = [];
|
||||
if (allowedRootDirectory) {
|
||||
paths.push(allowedRootDirectory);
|
||||
}
|
||||
if (dataDirectory) {
|
||||
paths.push(dataDirectory);
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user