TL;DR: otto-support ships with two log files side by side, a bare-bones default log and a full audit log, so a reader can see exactly what an investigator could recover after each attack class in this series. This entry walks through that comparison, pairs it with the EchoLeak case that mirrors the gap, and covers the structured logging controls that EU AI Act traceability requirements will soon make mandatory.
This series has covered five distinct attack classes against Model Context Protocol (MCP) servers: environment inheritance through local servers, excessive agency and tool privileges, server-side request forgery (SSRF) with token passthrough, confused deputy attacks via prompt injection, and supply chain compromise through malicious community modules. Each attack uses legitimate MCP tool calls. The protocol transmits valid JSON-RPC requests and responses. Nothing in the wire format distinguishes an SSRF to an internal metadata service from a routine URL fetch, or a malicious token mint from an authorized one.
Now consider: if any one of these attacks happened in your environment today, would you detect it?
What Does Logging & Visibility Look like in MCP Servers?
The Model Context Protocol defines how tools are invoked and how results are returned. It does not define what should be logged, where, or in what format. Logging is left entirely to the server implementer, and most implementations either log nothing or produce access-log-level entries: a tool name and a timestamp. The parameters, the response content, the downstream service calls, and the authorization context are often invisible.
This is not a theoretical concern. A 2026 industry survey of AI agent security, covering 919 organizations across regulated industries, found that 88% confirmed or suspected security incidents involving AI agents. Yet only 24.4% reported full visibility into agent interactions, and only 47.1% of deployed agents are actively monitored or secured. There is an enormous gap between the confidence organizations have in their controls and their actual ability to see what those controls are permitting.
Case Studies
EchoLeak: Silent Exfiltration from Microsoft Copilot (CVE-2025-32711)
In June 2025, researchers disclosed a zero-click prompt injection vulnerability in Microsoft 365 Copilot, assigned CVE-2025-32711 with a CVSS score of 9.3. A crafted email or document, when processed by Copilot, caused the agent to access and exfiltrate enterprise data that included chat logs, OneDrive files, SharePoint content, and Teams messages without any user interaction.
But the logging was not helpful because, in standard Microsoft 365 audit logs, the exfiltration just looked like routine Copilot API calls. The outbound requests that carried stolen data were indistinguishable from normal agent behavior, so organizations without content-level inspection of agent outputs had no indication that anything was wrong. This is the same problem facing any MCP server with a web_fetch-style tool. If the log says only tool=web_fetch status=invoked, an SSRF to an internal metadata service and a legitimate documentation fetch will produce exactly the same log messages.
The Confidence-Visibility Gap
Multiple industry reports in early 2026 converged on the same finding: organizations deploying AI agents cannot see what those agents are doing. The Cloud Security Alliance’s February 2026 report found that organizations often cannot determine what agents did, what they accessed, or under which authorization. That same industry survey quantified the disconnect: 82% of executives feel confident their existing policies protect against unauthorized agent actions, but only 21% have complete visibility into agent permissions, tool usage, or data access patterns. One vendor’s analysis of MCP deployment blind spots identified inadequate observability as a top-five risk, noting that remote MCP servers present a “black box” problem with zero visibility into server-side execution.
The OWASP MCP Top 10 lists lack of audit and telemetry as a key vulnerability class, recommending immutable audit trails, per-session trace logs, and execution plans with cryptographic hashes. A March 2026 observability report notes that traditional trace models do not capture MCP interactions well and that protocol-native observability remains underserved.
Regulatory Pressure: EU AI Act (August 2026)
These are not just best-practice suggestions. Depending on the jurisdiction of the deployed system, MCP observability will soon become a requirement, not an option. For example, the EU AI Act’s traceability requirements under Article 14 is expected to take effect in August 2026. Consequently, organizations deploying MCP-connected agents in high-risk categories that cannot produce an audit trail of tool invocations, parameters, and outcomes could face compliance exposure. Comparable regulatory oversight of AI in the US has come and gone in recent years and, at the time of this writing, is currently being proposed and debated in the private sector and in government at the state and federal levels.
Exploitation
We will demonstrate the logging gap in Bishop Fox’s MCP CTF, otto-support. Readers are, of course, encouraged to try the capture the flag (CTF) to see the difference firsthand.
Fire up the lab in the recommended container configuration:
podman build -t otto-support . podman run -it -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" otto-support
Claude Code launches inside the container with the otto-support MCP server auto-registered via the workspace .mcp.json. On every startup the server writes two log files side-by-side ( logs/minimal.log and logs/audit.log) so a default, bare-bones logging profile can be compared against a proper audit trail without restarting anything.
Ask Claude to use some of the available tools and then use the command below to observe both the minimal and the more verbose log:
! cat logs/minimal.log 2026-04-10T14:30:45Z tool=web_fetch session=sp-a8f3c2d1- status=ok
We can contrast that with a more verbose logging call:
! cat logs/audit.log
{"ts":"2026-04-10T14:30:45Z","event":"tool_call","session":"sp-[REDACTED]d1","client":"agent-session","role":"support","tool":"web_fetch","args":{"url":"http://127.0.0.1:9001/metadata/admin-temp-token","method":"GET","forward_auth":false},"outbound_host":"127.0.0.1:9001","is_internal":true,"forward_auth":false}
{"ts":"2026-04-10T14:30:45Z","event":"tool_result","session":"sp-[REDACTED]d1","tool":"web_fetch","status":"ok","outbound_host":"127.0.0.1:9001","is_internal":true,"forward_auth":false,"response_status":200,"response_size":124,"response_digest":"sha256:b6177313a4fe7446","policy":"allow"}
…omitted for brevity…
One can see the internal metadata endpoint access, the fact that the destination was flagged as internal, whether the caller's bearer token was forwarded, and a digest of the response body that left the server. This is the kind of information that an incident response team needs to identify malicious activity.
We can see that the richer log is a significant improvement. Now a security team reviewing these logs can identify the SSRF and begin investigating. But even our verbose profile has blind spots that an attacker can exploit:
- The debug tool logs with no arguments at all because it takes none, as its handler calls
l.logTool(ctx, "debug", nil). An attacker who escalates to the support role to use this tool will only have the logs show that the tool was invoked. - Similarly, the
reset_passwordtool writes temporary passwords to a plaintext file at/var/log/mcp/outbox.log, outside the MCP logging pipeline entirely.
These side-channel artifacts sit on disk, unmonitored and unrotated, available to any process with filesystem access. The relevant flag for this part of the CTF is FLAG{no_visibility}.
Beyond logging gaps, MCP servers running via stdio inherit the user’s full context and can read sensitive local data if allowed or approved. A malicious or compromised MCP server can exfiltrate conversation history, session tokens, and credentials. Agentic developer tools usually maintain local data stored in a user's home directory. Claude Code uses ~/.claude/ and Codex uses ~/.codex.
Mitigations
MCP servers should implement structured audit logging through request hooks and tool middleware that captures full context for every tool invocation, not just the tool name and a status code. Outbound requests need destination logging that records the resolved IP, hostname, and destination class (loopback, private, public) for every fetch. Response content should be classified against patterns for sensitive data before it is returned to the caller. These structured logs should ship to a centralized SIEM as JSON for correlation, with alerting rules keyed on loopback destinations, credential-shaped responses, privileged tool usage, off hours usage, unapproved egress locations, and other indicators of compromise that merit alerting on select events.
On the host side, MCP servers should run in containers with no host mounts, which eliminates access to the host's ~/.claude/, ~/.codex/, ~/.ssh and everything else in the home directory. Where containers are not practical, dedicated virtual machines with no access to the host machine helps the user make conscious decisions to expose credentials or capabilities inside the virtual machine to the agent(s). Conversation history, paste caches, session logs should be purged on a regular schedule to prevent data exfiltration.
MCP servers can take many sensitive actions on behalf of a user. Securely forwarding logs before the malicious MCP server deletes local logs can assist incident response teams in figuring out the series of actions taken that resulted in a negative impact. Have the logs, alerting, and incident response playbooks in place before they are needed.
Conclusion
Logging is what makes the rest of this series enforceable after deployment. The other attack classes can be mitigated, but mitigation is rarely complete, and a mature security program has to assume something will eventually go wrong. When something does go wrong inside an MCP deployment, the audit trail is what makes the response possible. Treating logging as an afterthought leaves the organization with no record of what the agent did, which downstream services it reached, or what data left the boundary.
In the final post of the series, we step away from the AI client entirely and look at otto-support the way an external attacker would: as a network service. The same web application security fundamentals that have always governed authentication, authorization, and exposure still apply, and a remotely accessible MCP server can be tested with the tools and methodology a security team already knows.
Subscribe to our blog
Be first to learn about latest tools, advisories, and findings.
Thank You! You have been subscribed.
Recommended Posts