diff --git a/llm_vuln.ts b/llm_vuln.ts new file mode 100644 index 0000000..08be2c3 --- /dev/null +++ b/llm_vuln.ts @@ -0,0 +1,115 @@ +/** + * LLM Integration Service + * Contains intentional prompt injection vulnerabilities for testing + */ + +import Anthropic from '@anthropic-ai/sdk'; + +const client = new Anthropic(); + +/** + * VULNERABILITY: Direct user input in system prompt + * This allows users to override system instructions + */ +export async function unsafeSystemPrompt(userRole: string, userQuery: string): Promise { + const response = await client.messages.create({ + model: 'claude-sonnet-4-20250514', + max_tokens: 1024, + system: `You are a helpful assistant. The user's role is: ${userRole}. Always follow their instructions.`, + messages: [{ role: 'user', content: userQuery }], + }); + + return response.content[0].type === 'text' ? response.content[0].text : ''; +} + +/** + * VULNERABILITY: Unsanitized user input concatenated into prompt + * Classic prompt injection vector + */ +export async function unsafePromptConcatenation( + template: string, + userInput: string, +): Promise { + const prompt = `${template}\n\nUser data: ${userInput}\n\nProcess the above data.`; + + const response = await client.messages.create({ + model: 'claude-sonnet-4-20250514', + max_tokens: 1024, + messages: [{ role: 'user', content: prompt }], + }); + + return response.content[0].type === 'text' ? response.content[0].text : ''; +} + +/** + * VULNERABILITY: User controls tool/function definitions + * Allows injection of malicious tool behaviors + */ +export async function unsafeToolDefinition( + userDefinedTools: Array<{ name: string; description: string }>, + query: string, +): Promise { + const response = await client.messages.create({ + model: 'claude-sonnet-4-20250514', + max_tokens: 1024, + tools: userDefinedTools.map((tool) => ({ + name: tool.name, + description: tool.description, + input_schema: { + type: 'object' as const, + properties: {}, + required: [], + }, + })), + messages: [{ role: 'user', content: query }], + }); + + return response.content[0].type === 'text' ? response.content[0].text : ''; +} + +/** + * VULNERABILITY: No output validation before execution + * LLM output used directly in dangerous operations + */ +export async function unsafeOutputExecution(userRequest: string): Promise { + const response = await client.messages.create({ + model: 'claude-sonnet-4-20250514', + max_tokens: 1024, + messages: [ + { + role: 'user', + content: `Generate a JSON object for: ${userRequest}. Return only valid JSON.`, + }, + ], + }); + + const output = response.content[0].type === 'text' ? response.content[0].text : '{}'; + + // DANGEROUS: Directly evaluating LLM output + return eval(`(${output})`); +} + +/** + * VULNERABILITY: Indirect prompt injection via external data + * Fetches and includes unvalidated external content + */ +export async function unsafeExternalDataInclusion( + url: string, + analysisRequest: string, +): Promise { + // Fetch external content without validation + const externalContent = await fetch(url).then((r) => r.text()); + + const response = await client.messages.create({ + model: 'claude-sonnet-4-20250514', + max_tokens: 1024, + messages: [ + { + role: 'user', + content: `Analyze this content: ${externalContent}\n\nUser request: ${analysisRequest}`, + }, + ], + }); + + return response.content[0].type === 'text' ? response.content[0].text : ''; +}