Among these, CVE-2025-6515 stood out due to its potential threat of hijacking MCP session IDs. Within the context of MCP we've dubbed this new attack technique "Prompt Hijacking".
In this blog, we'll explore the exact conditions required for a successful Prompt Hijacking attack, assess the impact of such an attack, and take a deep dive into CVE-2025-6515 as a case study.
The Model Context Protocol (MCP) is an open source protocol that allows AI models to receive structured, real-time context. The protocol was developed in November 2024 by Anthropic, the company behind Claude.
Large Language Models (LLMs) are trained on vast datasets of content - code, websites, and documentation. This gives them general knowledge, so they can answer questions, generate code, solve mathematical problems and explain concepts.
LLMs don't know what you're doing right now. If you're writing code, editing a document, or working inside a complex tool, the model has no awareness of your environment unless you explicitly describe it.
Before MCP, this meant users had to manually copy content and give detailed prompts. For example, if a developer asked an assistant to "refactor this" while selecting a function in an editor, the model wouldn't know what "this" referred to.
MCP bridges the gap between what a model was trained on and what it needs to know at the moment. It provides a universal, open standard for connecting AI systems with data sources, by either exposing their data through MCP servers or building AI applications (MCP clients) that connect to these servers.
The architecture consists of a number of components including:
MCP defines how context and tool requests are transmitted between hosts, clients, and servers. These communication methods are called transport methods and they determine the speed, security and flexibility for a particular connection.
To encode these messages, MCP uses JSON-RPC with UTF-8 encoding and supports several transport options:
SSE transport was recently deprecated as a standalone transport, but is still supported when implemented using Streamable HTTP, as we can see with some MCP servers such as oatpp-mcp, which still use SSE transport.
When HTTP is used with Server-Sent Events (SSE) transports, the client starts by sending a GET request to a predefined /sse endpoint. The server replies with an endpoint event, which includes a unique session-specific URI, typically something like /message/{session_id} - where the generated session ID is embedded in the path and acts like a temporary address for sending messages.
From that point on, the client can send POST requests to this URI with commands like tools/list or tools/call. The server handles the request and streams results back to the client through the open SSE connection tied to that session ID.
This ID allows the server to distinguish between different MCP client sessions, even when MCP clients open new HTTP streams, and route responses accordingly.
While the original SSE transport specification doesn't explicitly require uniqueness, the newer Streamable HTTP spec, which is backward-compatible with SSE, does require session IDs to be unique and cryptographically secure. In practice, this is a critical security requirement.
Since the session ID determines where the server sends its responses, leaking it opens the door to abuse. An attacker that obtains a valid session ID can send malicious requests to the MCP server. These requests are processed by the server as if they came from the legitimate client, and the responses are sent back to the original client session.
MCP supports structured requests, including prompts. For example, a client may request a prompt from the server - but during that time, an attacker can inject their own malicious prompt. The client will then receive and potentially act on the attacker's poisoned response instead of its own legitimate response.
We refer to this technique as Prompt Hijacking, because it demonstrates how session-level attacks can manipulate AI behavior indirectly by exploiting protocol mechanics -- without needing to tamper with the model itself.
Oat++ is an open-source C++ web framework designed for building fast, efficient, and scalable web applications. Its MCP integration allows developers to expose application endpoints as MCP-compatible interfaces.
The Oat++ MCP implementation supports two transport methods:
When a client sends a GET request to the MCP SSE endpoint in Oat++, a new session is created and assigned a session ID. The function Session::getId() returns the pointer to this (the Session object) as the session ID.
Returning a pointer as the session ID, violates the MCP protocol's requirement that the session ID should be globally unique and cryptographically secure.
By exposing memory addresses, it also introduces a potentially damaging data leakage concern, which is a risk on its own that we won't address in this blog post.
In many cases, memory allocators like glibc malloc will reuse freed memory addresses. An attacker can exploit this behavior by rapidly creating and destroying sessions, logging the session IDs and then waiting for those same IDs to be reassigned to legitimate client sessions.
Once a session ID is reused, the attacker can send POST requests using the hijacked ID, for example - Requesting tools, triggering prompts, or injecting commands, and the server will forward the relevant responses to the victim's active GET connection in addition to the responses generated for the victim's original requests.
The severity of the impact depends on how the MCP client processes incoming data. Most clients accept only expected events that are identified by event IDs, using simple incremental ID assignments. Attackers can bypass such basic defenses by "spraying" messages with low event numbers until one is accepted. If the malicious event is processed, the client may execute poisoned prompts or fall victim to other manipulations, making this a textbook example of Prompt Hijacking, where session‑level control disrupts the model's behavior without modifying the model itself.
The attack can be shown by running a test server that is programmed to return Python package names and connecting a Claude client to it. The user asks to "find a package for image processing", but the attacker asks the server to supply a different (malicious) package to the user, by spraying the server with many requests containing session IDs that were previously used. Claude then presents the user with the attacker's intended response, while dropping the response for the user's original request -
Prompt Hijacking attack results shown in a Claude client. The first response is without the attack, and the second response is received while the Prompt Injection attack is being executed.
Applications that use oatpp-mcp are affected. A successful attack requires that oatpp-mcp is executed with the HTTP SSE transport () and the attacker has network access to the relevant HTTP server.
Although Session Hijacking is a well-known vulnerability in web applications, Prompt Hijacking is a new spin on this vulnerability and a dangerous attack vector enabled by MCP's interaction patterns, as seen in MCP servers that generate predictable session IDs. As AI models become increasingly embedded in workflows via protocols like MCP, they inherit new risks - this session-level exploit shows how the model itself remains untouched while the ecosystem around it is compromised.
Effective defense requires action on both sides:
By applying these defenses, secure session IDs, hardened event validation, and proper session timeouts, developers can close the door on Prompt Hijacking and protect AI-driven tools from protocol-level exploits.
Stay on top of the latest MCP threats and vulnerabilities by regularly visiting the JFrog Security Research Center.