UNPKG

mlld

Version:

mlld: a modular prompt scripting language

1 lines 8.39 kB
{"version":3,"sources":["../security/taint/TaintTracker.ts"],"names":["TaintLevel","TaintTracker","taintMap","Map","mark","id","value","taint","source","advisoryIds","set","sources","advisories","getTaint","get","markImport","content","startsWith","length","map","a","isLLMCommand","command","llmPatterns","baseCommand","split","some","pattern","test","markCommandOutput","output","combineTaint","taints","priority","level","includes","requiresApprovalForExecution","describeTaint","descriptions"],"mappings":"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","file":"chunk-KYJC7SAY.mjs","sourcesContent":["/**\n * Taint tracking system for mlld\n * Tracks the trust level of data based on its origin\n */\n\nexport enum TaintLevel {\n TRUSTED = 'trusted', // Literal strings in .mld files\n REGISTRY_SAFE = 'registry_safe', // Registry import with no advisories\n REGISTRY_WARNING = 'registry_warning', // Registry import with advisories\n GIST_DIRECT = 'gist_direct', // Direct gist import\n USER_INPUT = 'user_input', // From user prompts\n FILE_SYSTEM = 'file_system', // From local files\n NETWORK = 'network', // From URLs\n LLM_OUTPUT = 'llm_output', // From LLM responses - HIGHEST RISK\n COMMAND_OUTPUT = 'command_output', // From command execution\n MIXED = 'mixed' // Combined sources\n}\n\nexport interface TaintedValue<T = unknown> {\n value: T;\n taint: TaintLevel;\n sources: string[]; // Track origin for forensics\n advisories?: string[]; // Advisory IDs if any\n}\n\n/**\n * Tracks taint levels for values throughout execution\n */\nexport class TaintTracker {\n private taintMap = new Map<string, TaintedValue>();\n \n /**\n * Mark a value with a taint level\n */\n mark<T = unknown>(\n id: string, \n value: T, \n taint: TaintLevel, \n source: string,\n advisoryIds?: string[]\n ): void {\n this.taintMap.set(id, {\n value,\n taint,\n sources: [source],\n advisories: advisoryIds\n });\n }\n \n /**\n * Get taint info for a value\n */\n getTaint<T = unknown>(id: string): TaintedValue<T> | undefined {\n return this.taintMap.get(id) as TaintedValue<T> | undefined;\n }\n \n /**\n * Mark an import based on its source and advisories\n */\n markImport(\n id: string,\n content: string, \n source: string, \n advisories: Array<{ id: string }>\n ): TaintLevel {\n let taint: TaintLevel;\n \n if (source.startsWith('mlld://registry/')) {\n taint = advisories.length > 0 \n ? TaintLevel.REGISTRY_WARNING \n : TaintLevel.REGISTRY_SAFE;\n } else if (source.startsWith('mlld://gist/')) {\n taint = TaintLevel.GIST_DIRECT;\n } else if (source.startsWith('http://') || source.startsWith('https://')) {\n taint = TaintLevel.NETWORK;\n } else {\n taint = TaintLevel.FILE_SYSTEM;\n }\n \n this.mark(\n id, \n content, \n taint, \n source,\n advisories.map(a => a.id)\n );\n \n return taint;\n }\n \n /**\n * Check if a command comes from an LLM\n */\n isLLMCommand(command: string): boolean {\n const llmPatterns = [\n /^(claude|anthropic|ai)/i,\n /^(gpt|openai|chatgpt)/i,\n /^(llm|ai-|ml-)/i,\n /^(bard|gemini|palm)/i,\n /^(mistral|llama|alpaca)/i,\n ];\n \n const baseCommand = command.split(/\\s+/)[0];\n return llmPatterns.some(pattern => pattern.test(baseCommand));\n }\n \n /**\n * Mark command output with appropriate taint\n */\n markCommandOutput(\n id: string,\n output: string,\n command: string,\n source: string\n ): TaintLevel {\n // If command is an LLM, mark as LLM_OUTPUT (highest risk)\n const taint = this.isLLMCommand(command) \n ? TaintLevel.LLM_OUTPUT \n : TaintLevel.COMMAND_OUTPUT;\n \n this.mark(id, output, taint, `cmd:${command}`);\n return taint;\n }\n \n /**\n * Combine taint levels (always use the most restrictive)\n */\n combineTaint(taints: TaintLevel[]): TaintLevel {\n // Priority order (highest risk first)\n const priority = [\n TaintLevel.LLM_OUTPUT,\n TaintLevel.REGISTRY_WARNING,\n TaintLevel.NETWORK,\n TaintLevel.GIST_DIRECT,\n TaintLevel.COMMAND_OUTPUT,\n TaintLevel.USER_INPUT,\n TaintLevel.REGISTRY_SAFE,\n TaintLevel.FILE_SYSTEM,\n TaintLevel.TRUSTED\n ];\n \n // Find the highest risk taint\n for (const level of priority) {\n if (taints.includes(level)) {\n return level;\n }\n }\n \n return TaintLevel.MIXED;\n }\n \n /**\n * Check if a taint level requires approval for command execution\n */\n requiresApprovalForExecution(taint: TaintLevel): boolean {\n return [\n TaintLevel.LLM_OUTPUT,\n TaintLevel.REGISTRY_WARNING,\n TaintLevel.NETWORK,\n TaintLevel.GIST_DIRECT\n ].includes(taint);\n }\n \n /**\n * Get human-readable description of taint level\n */\n describeTaint(taint: TaintLevel): string {\n const descriptions: Record<TaintLevel, string> = {\n [TaintLevel.TRUSTED]: 'Trusted (literal in source)',\n [TaintLevel.REGISTRY_SAFE]: 'Registry module (no advisories)',\n [TaintLevel.REGISTRY_WARNING]: '⚠️ Registry module with security advisories',\n [TaintLevel.GIST_DIRECT]: 'Direct gist import',\n [TaintLevel.USER_INPUT]: 'User input',\n [TaintLevel.FILE_SYSTEM]: 'Local file',\n [TaintLevel.NETWORK]: 'Network content',\n [TaintLevel.LLM_OUTPUT]: '🚨 LLM-generated content',\n [TaintLevel.COMMAND_OUTPUT]: 'Command output',\n [TaintLevel.MIXED]: 'Mixed sources'\n };\n \n return descriptions[taint] || taint;\n }\n}"]}