/** * Secure File Access Module * * Provides security utilities for file operations: * - Symlink detection to prevent symlink attacks * - Safe file reading with path traversal and symlink protection * - Combines safeJoin() validation with lstat() symlink checks * * Security features: * - Rejects symlinks to prevent reading files outside project * - Validates paths using safeJoin() to prevent path traversal * - Uses lstat() instead of stat() to detect symlinks * - Handles Windows junctions and symbolic links */ import * as fs from 'node:fs'; /** * Result of a symlink check */ export interface SymlinkCheckResult { /** Whether the path is a symlink */ isSymlink: boolean; /** The path that was checked */ path: string; /** Target of the symlink (if it is one and could be resolved) */ target?: string; } /** * Options for secure file operations */ export interface SecureFileOptions { /** * Behavior when a symlink is encountered: * - 'error': Throw an error (default for explicit file access) * - 'skip': Return null/false without error (for indexing operations) */ symlinkBehavior: 'error' | 'skip'; } /** * Check if a path is a symbolic link * * Uses lstat() to detect symlinks without following them. * Handles both Unix symbolic links and Windows junctions/symbolic links. * * @param filePath - Absolute path to check * @returns Promise resolving to true if path is a symlink * * @example * ```typescript * const isLink = await isSymlink('/path/to/file'); * if (isLink) { * console.log('Path is a symbolic link - potential security risk'); * } * ``` */ export declare function isSymlink(filePath: string): Promise; /** * Check if a path is a symbolic link (synchronous version) * * @param filePath - Absolute path to check * @returns true if path is a symlink */ export declare function isSymlinkSync(filePath: string): boolean; /** * Detailed symlink check with target resolution * * @param filePath - Absolute path to check * @returns Symlink check result with details */ export declare function checkSymlink(filePath: string): Promise; /** * Validate and create a secure absolute path * * Combines path traversal prevention with symlink detection. * Returns null if path is invalid or is a symlink. * * @param basePath - Base directory path * @param relativePath - Relative path to join * @param options - Security options * @returns Validated absolute path, or null if invalid/symlink */ export declare function secureResolvePath(basePath: string, relativePath: string, options?: SecureFileOptions): Promise; /** * Safely check if a file exists within a base directory * * Validates path security and checks existence without following symlinks. * * @param basePath - Base directory path * @param relativePath - Relative path to check * @param options - Security options * @returns Promise resolving to true if file exists and is not a symlink * * @example * ```typescript * const exists = await safeFileExists('/project', 'src/index.ts'); * if (exists) { * // Safe to read the file * } * ``` */ export declare function safeFileExists(basePath: string, relativePath: string, options?: SecureFileOptions): Promise; /** * Safely read a file with path traversal and symlink protection * * Combines: * 1. safeJoin() validation for path traversal prevention * 2. lstat() check for symlink detection * 3. Actual file read * * @param basePath - Base directory path * @param relativePath - Relative path to the file * @param options - Security options * @returns Promise resolving to file content as string * @throws MCPError with SYMLINK_NOT_ALLOWED if file is a symlink * @throws MCPError with FILE_NOT_FOUND if path traversal detected or file doesn't exist * * @example * ```typescript * // For explicit file access (errors on symlinks) * const content = await safeReadFile('/project', 'src/index.ts', { * symlinkBehavior: 'error' * }); * * // For indexing operations (skips symlinks) * const content = await safeReadFile('/project', 'src/index.ts', { * symlinkBehavior: 'skip' * }); * ``` */ export declare function safeReadFile(basePath: string, relativePath: string, options?: SecureFileOptions): Promise; /** * Safely read a file as a Buffer with path traversal and symlink protection * * @param basePath - Base directory path * @param relativePath - Relative path to the file * @param options - Security options * @returns Promise resolving to file content as Buffer */ export declare function safeReadFileBuffer(basePath: string, relativePath: string, options?: SecureFileOptions): Promise; /** * Create a secure read stream with symlink protection * * For streaming large files while maintaining security checks. * Note: Symlink check happens before stream creation. * * @param basePath - Base directory path * @param relativePath - Relative path to the file * @param options - Security options * @returns Promise resolving to read stream, or null if symlink with skip behavior * @throws MCPError if symlink with error behavior or invalid path */ export declare function safeCreateReadStream(basePath: string, relativePath: string, options?: SecureFileOptions): Promise; /** * Check if a file should be skipped during indexing due to being a symlink * * This is a convenience function for indexing operations that want to * skip symlinks with a warning rather than throwing an error. * * @param absolutePath - Absolute path to check * @returns true if the file is a symlink and should be skipped */ export declare function shouldSkipForIndexing(absolutePath: string): Promise; /** * Validate an absolute path is not a symlink * * For use when you already have a validated absolute path but need * to add symlink protection. * * @param absolutePath - Absolute path to validate * @param options - Security options * @returns true if path is safe, false if it's a symlink (with skip behavior) * @throws MCPError if symlink with error behavior */ export declare function validateNotSymlink(absolutePath: string, options?: SecureFileOptions): Promise; //# sourceMappingURL=secureFileAccess.d.ts.map