UNPKG

cc-inspect-mcp

Version:

MCP server for inspecting and searching Claude Code conversation history with boolean search support

53 lines (52 loc) 1.89 kB
import { resolve, isAbsolute, relative, join } from 'path'; import { homedir } from 'os'; export class SecurityValidator { allowedBasePath; constructor(basePath) { // Default to Claude's directory, but allow override this.allowedBasePath = resolve(basePath || join(homedir(), '.claude')); } /** * Validates that a path is within the allowed directory * Prevents directory traversal attacks */ validatePath(inputPath) { try { const resolvedPath = resolve(inputPath); const relativePath = relative(this.allowedBasePath, resolvedPath); // If the relative path starts with '..', it's outside allowed directory return !relativePath.startsWith('..') && !isAbsolute(relativePath); } catch { return false; } } /** * Sanitizes search queries to prevent injection attacks * Allows only safe characters for boolean search */ sanitizeQuery(query) { // Allow alphanumeric, spaces, and boolean operators // Remove any potential script injection attempts return query .replace(/<script[^>]*>.*?<\/script>/gi, '') .replace(/<[^>]+>/g, '') // Remove any HTML tags .slice(0, 1000); // Limit query length } /** * Validates that session IDs are valid UUIDs */ validateSessionId(sessionId) { const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; return uuidRegex.test(sessionId); } /** * Sanitizes log output to prevent sensitive data exposure */ sanitizeForLogging(content, maxLength = 200) { return content .slice(0, maxLength) .replace(/[^\x20-\x7E\n]/g, '') // Remove non-printable characters + (content.length > maxLength ? '...' : ''); } }