/** * Input Validator - Security validation for user inputs * * Validates and sanitizes user inputs to prevent injection attacks */ /** * Validation result for tool call arguments */ export interface ValidationResult { errors: string[]; metrics: { inputDepth: number; inputSizeBytes: number; maxArrayLength: number; }; valid: boolean; warnings: string[]; } export declare class InputValidationError extends Error { readonly field: string; readonly value: string; constructor(message: string, field: string, value: string); } /** * Configuration options for InputValidator instance */ export interface InputValidatorOptions { maxArrayLength?: number; maxObjectDepth?: number; maxStringLength?: number; maxTotalSize?: number; } /** * Validation utilities for security-critical inputs */ export declare class InputValidator { /** * Maximum safe length for various inputs */ private static readonly MAX_LENGTHS; /** * Instance configuration for validate() method */ private readonly config; constructor(options?: InputValidatorOptions); /** * Validate any input value against configured limits and malicious patterns */ validate(input: unknown): ValidationResult; /** * Check for malicious patterns in a string. These are hard rejections (pushed * to `errors`, not `warnings`) — a matched pattern makes the input invalid, * consistent with `validateToolCallArgs`'s treatment of the same pattern list. */ private checkMaliciousPatterns; /** * Validate git branch name * * Git branch names must: * - Not contain special shell characters * - Not start with ., /, or - * - Not contain .. * - Only contain alphanumeric, -, _, / * - Not end with .lock * - Not be empty */ static validateBranchName(name: string): void; private static checkBranchNameBasics; private static checkBranchNameCharacters; private static checkBranchNameGitRules; private static checkBranchNameSecurity; /** * Validate and sanitize file path * * Ensures path: * - Is within allowed directory * - Doesn't contain path traversal (..) * - Is not a symbolic link outside allowed area * - Doesn't contain null bytes */ static validatePath(targetPath: string, allowedRoot: string): string; /** * Resolve a path to its canonical (symlink-free) absolute form, following * symlinks on the longest ancestor that already exists on disk and * reattaching any remaining (not-yet-created) segments unresolved. */ private static resolveExistingSymlinks; /** * Validate git ref (branch, tag, commit) * * Refs must: * - Only contain safe characters * - Not contain shell metacharacters * - Not be excessively long */ static validateGitRef(ref: string): void; /** * Validate and sanitize reason text * * Used for lock reasons, commit messages, etc. */ static validateReasonText(text: string): string; /** * Validate exploration ID format * * Should match pattern: exp-{nanoid} */ static validateExplorationId(id: string): void; /** * Validate session ID format — a bare nanoid (no fixed prefix, unlike * exploration IDs), matching `generateSessionId()`'s `nanoid(12)` output. * `SessionStore.getSessionPath()` joined this into a filesystem path with * no validation at all — `sessionId` reaches it as a raw CLI argument via * `session delete `/`show`/`export`, so an unvalidated `../` sequence * was a live, traversal-based arbitrary-`.json`-file-delete primitive. */ static validateSessionId(id: string): void; /** * Validate a batch local ID — matches `generateLocalId()`'s exact output * shape (a 16-char lowercase-hex sha256 substring), stricter than * `validateSessionId`'s general charset since this ID is never * user-chosen. `batch-session.ts`'s `batchFilePath()`/`persistBatch()` * joined this into a filesystem path with no validation at all — * `localId` reaches it as a raw CLI argument via `batch status/results/ * cancel `, so an unvalidated `../` sequence was a live * traversal-based arbitrary-file-read primitive, chained into an * arbitrary-file-write primitive via `updateBatch()` re-persisting a * loaded file's own (attacker-controlled) `localId` field. */ static validateBatchId(id: string): void; /** * Validate numeric input */ static validateNumber(value: number, min: number, max: number, name: string): void; /** * Sanitize command output * * Remove potentially dangerous content from command output * before logging or displaying */ static sanitizeCommandOutput(output: string): string; } /** * Validate MCP tool call arguments for security and resource constraints * * Checks for: * - Maximum input size (prevent DoS) * - Maximum nesting depth (prevent stack overflow) * - Maximum array lengths (prevent memory exhaustion) * - Malicious patterns in strings */ export declare function validateToolCallArgs(args: Record): ValidationResult; /** * Validate completion options (similar to validateToolCallArgs but for LLM completions) * * This is a wrapper around validateToolCallArgs for completion-specific validation */ export declare function validateCompletionOptions(options: Record): ValidationResult; /** * Validate any input using the InputValidator * * Convenience function for validating arbitrary inputs */ export declare function validateInput(input: unknown): ValidationResult; /** * Validate that a path is not in the forbidden write paths. * Throws an error if the path targets the .valora/ or data/ folders or other protected system paths. * * @param path - The path to validate (can be relative or absolute) * @param operation - The operation being attempted (e.g., "write to", "delete", "modify") * @throws Error if the path is forbidden */ export declare function validateNotForbiddenPath(path: string, operation: string): void; /** * Check if a path is forbidden without throwing an error. * Useful for conditional logic where you need to check before attempting an operation. * * @param path - The path to check (can be relative or absolute) * @returns true if the path is forbidden, false otherwise */ export declare function isForbiddenPath(path: string): boolean; //# sourceMappingURL=input-validator.d.ts.map