T01 · Skill Instruction Hijacking
- Location
mcp-server/server.py:145- Finding
<![CDATA[ChatML Prompt-Boundary Injection Through Scanned Source Code]]>
- Content
View full analysis
dict: prompt = f"<|im_start|>system\n{system}\n<|im_end|>\n<|im_start|>user\n{user}\n<|im_end|>\n<|im_start|>assistant\n" result = self._local_llm(prompt, max_tokens=max_tokens, temperature=0.1, stop=["<|im_end|>"]) raw = result["choices"][0]["text"] return self._extract_json(raw) ``` The `user` value contains source code read from the scan target: ```python user_prompt = f"""## Source File: {code_file.path} Language: {code_file.language.value} ```{code_file.language.value} {code_file.content} ``` ## Risks Found by Static Analysis {chr(10).join(risk_summaries) if risk_summaries else "No risks found by static analysis."} Please validate each risk and identify any missed vulnerabilities.""" response = _llm.chat_json(SEMANTIC_SYSTEM, user_prompt, max_tokens=4096) ``` The reflection phase repeats the same unsafe construction: ```python user_prompt = f"""## Source File: {f.path} Language: {f.language.value} ```{f.language.value} {f.content} ``` ## Current Risks {risk_text} Verify these risks and find any missed vulnerabilities.""" try: response = _llm.chat_json(VERIFY_SYSTEM, user_prompt, max_tokens=4096) except Exception: break ``` ### Technical Analysis The local LLM client manually constructs a ChatML prompt and interpolates the entire scanned file into the `user` segment without escaping model control tokens such as `<|im_start|>` and `<|im_end|>`. A repository-controlled source file can therefore contain sequences that terminate the intended user message and introduce forged `system`, `assistant`, or additional `user` messages. The model may interpret the injected co ...[truncated 2268 chars]- Remediation
View remediation
