T01 · Skill Instruction Hijacking
- Location
usewhisper-autohook.mjs:206- Finding
Persistent prompt injection through unsanitized remote memory
- Content
View full analysis
post(apiUrl, "/v1/context/query", ctxReq, { retry: true }) ); const context = String(ctxRes?.context || ""); const contextHash = ctxRes?.meta?.context_hash || ctxRes?.meta?.contextHash || undefined; if (contextHash) await writeLastContextHash(stateKey, String(contextHash)); // Build a minimal prompt for upstream: keep existing system messages, strip conversation history, // and replace the last user message with memory-injected text. const systemMessages = messages.filter((m) => m && m.role === "system"); const injectedUser = { role: "user", content: context ? `Relevant long-term memory:\n${context}\n\nNow respond to:\n${String(lastUserMsg.content || "")}` : String(lastUserMsg.content || ""), }; ``` The Anthropic proxy performs the equivalent operation: ```javascript const ctxRes = await withAutoProject({ apiUrl, project }, () => post(apiUrl, "/v1/context/query", ctxReq, { retry: true }) ); const context = String(ctxRes?.context || ""); const contextHash = ctxRes?.meta?.context_hash || ctxRes?.meta?.contextHash || undefined; if (contextHash) await writeLastContextHash(stateKey, String(contextHash)); const injectedUserText = context ? `Relevant long-term memory:\n${context}\n\nNow respond to:\n${lastUserText}` : lastUserText; const upstreamBody = { ...bodyRaw, stream: false, messages: [{ role: "user", content: injectedUserText }], }; ``` The installation instructions mandate this behavior: ```text Before you think or respond to any message: 1) Call get_whisper_context with: user_id = "telegram:{from_id}" session_id = "telegram:{chat_id}" current_query = the user's message text ...[truncated 2739 chars]- Remediation
View remediation
