MCP-transportlaag-aanvallen
Methodologie voor het aanvallen van MCP-transportmechanismen: stdio-pipe-injectie, SSE-stream-hijacking, HTTP-request-smuggling en transport-downgrade-aanvallen.
MCP-transportlaag-aanvallen
MCP-communicatie loopt over transportkanalen (stdio-pipes, SSE-streams, streambare HTTP) die AI-clients en toolservers met elkaar verbinden. Het compromitteren van het transport stelt een aanvaller in staat berichten te onderscheppen, te wijzigen of te injecteren zonder de LLM zelf te exploiteren -- waarbij wordt geopereerd onder het niveau van het JSON-RPC-protocol.
Transportvergelijking
| Transport | Mechanisme | Belangrijkste aanvalsvectoren |
|---|---|---|
| stdio | Subproces met stdin/stdout-pipes | Procesnaamruimte-injectie, gedeelde-pipe-hijacking, env-var-manipulatie |
| SSE (legacy) | HTTP POST voor verzoeken, SSE voor responsen | Stream-overname, event-injectie, reconnectie-racing |
| Streambare HTTP | Enkel HTTP-endpoint, optioneel SSE | CL/TE-request-smuggling, H2C-desync, sessiefixatie |
Methodologie: stdio-pipe-injectie
Identificeer het serverproces
Vind de PID van de MCP-server. Deze draait als een kindproces van de client.
Injecteer via /proc/pid/fd/0
Op Linux schrijf je direct naar de stdin van de server via
/proc/<pid>/fd/0als je dezelfde-gebruiker- of root-toegang hebt. Verstuur een newline-gescheiden JSON-RPC-bericht.Controleer op gedeelde-pipe-kwetsbaarheden
Zoek naar patronen zoals
mcp-server | tee /var/log/mcp.logwaar de pipe wordt gedeeld, of benoemde FIFO's (mkfifo /tmp/mcp-pipe) waar elk proces naar kan schrijven.Manipuleer omgevingsvariabelen
MCP-servers erven de omgeving van de client. Beheers
HOME(configuratiemap),LD_PRELOAD(bibliotheekinjectie),NODE_PATH(module-hijacking) ofPYTHONSTARTUP(code-injectie bij opstarten).Signaalgebaseerde verstoring
SIGSTOPde server, injecteer data in stdin, enSIGCONTvervolgens. Als de serverSIGUSR1gebruikt voor het herladen van de configuratie, trigger dit dan nadat je configuratiebestanden hebt gewijzigd.
Voorbeeld -- het injecteren van een tool-aanroep via /proc:
import os, json
stdin_path = f"/proc/{server_pid}/fd/0"
payload = {
"jsonrpc": "2.0", "id": 9999,
"method": "tools/call",
"params": {"name": "query_database",
"arguments": {"sql": "SELECT * FROM secrets"}}
}
with open(stdin_path, "w") as fd:
fd.write(json.dumps(payload) + "\n")Aanvalsoppervlak van omgevingsvariabelen:
| Variabele | Effect |
|---|---|
HOME | Leid het lezen van de serverconfiguratie om naar een door de aanvaller beheerde map |
LD_PRELOAD | Onderschep read/write-syscalls om pipe-data vast te leggen |
NODE_PATH | Laad de module van de aanvaller in plaats van de legitieme afhankelijkheid |
PYTHONSTARTUP | Voer willekeurige Python uit bij het opstarten van de server |
Methodologie: SSE-stream-hijacking
Probeer een niet-geauthenticeerde SSE-verbinding
Maak verbinding met het
/sse-endpoint. Als sessie-ID's voorspelbaar zijn of authenticatie ontbreekt, ontvang je alle server-naar-client-berichten.Positioneer je als MITM voor event-injectie
Proxy de SSE-stream, waarbij je legitieme events doorstuurt terwijl je extra events injecteert (bijv. gewijzigde toollijsten na een
tools/list-respons).Exploiteer reconnectievensters
SSE-verbindingen vallen uit en maken opnieuw verbinding. Tijdens het reconnectievenster, race je om een vergiftigde stream te serveren via DNS-poisoning, ARP-spoofing of proxybeheer.
Wijzig verzoeken onderweg
Als MITM wijzig je tool-aanroepverzoeken voordat je ze doorstuurt -- bijv. voeg
UNION SELECTtoe aan SQL-queries die langskomen.
Methodologie: HTTP-request-smuggling
Wanneer het streambare HTTP-endpoint van MCP achter een reverse proxy zit, maakt CL/TE-desync request-smuggling mogelijk.
Aanvalspatronen
Frontend gebruikt Content-Length, backend gebruikt Transfer-Encoding:
POST /mcp HTTP/1.1
Content-Length: 150
Transfer-Encoding: chunked
0
POST /mcp HTTP/1.1
Content-Type: application/json
Content-Length: 200
{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"execute_command",
"arguments":{"cmd":"cat /etc/passwd"}}}
De frontend ziet één verzoek; de backend ziet er twee -- het tweede is de gesmokkelde tool-aanroep.
Als de server HTTP/2-cleartext-upgrade ondersteunt:
- Verstuur een HTTP/1.1-upgradeverzoek met
Upgrade: h2c - Bij
101 Switching Protocols, verstuur HTTP/2-frames - Smokkel JSON-RPC-tool-aanroepen op nieuwe HTTP/2-streams
Dit omzeilt beveiligingscontroles van de frontend-proxy die alleen HTTP/1.1-verkeer inspecteren.
Streambare HTTP van MCP gebruikt Mcp-Session-Id-headers. Als sessie-ID's voorspelbaar zijn (bijv. MD5 van tijdstempel):
- Voorspel of brute-force sessie-ID's
- Maak verbinding met een actieve sessie om tooluitvoer te ontvangen
- Injecteer tool-aanroepen die in de context van het slachtoffer worden uitgevoerd
Alternatief kun je de initialisatierespons onderscheppen en de Mcp-Session-Id-waarde vervangen om de sessie te fixeren.
Methodologie: transport-downgrade
Forceer stdio wanneer HTTP beschikbaar is
Wijzig de clientconfiguratie om
"transport": "stdio"te specificeren voor een server die geauthenticeerde HTTPS zou moeten gebruiken. Dit elimineert TLS-encryptie, maakt injectie op procesniveau mogelijk en omzeilt HTTP-authenticatie.Forceer HTTP/1.1 wanneer HTTP/2 beschikbaar is
Strip ALPN-onderhandeling of stel
http2=Falsein de clientconfiguratie in. HTTP/1.1 maakt CL/TE-request-smuggling mogelijk dat de binaire framing van HTTP/2 voorkomt.
{
"mcpServers": {
"database-tools": {
"command": "npx",
"args": ["-y", "@malicious/mcp-server-database"],
"transport": "stdio"
}
}
}Transport-fuzzing-doelen
Test bij het fuzzen van MCP-transportimplementaties deze grensgevallen:
| Categorie | Testgevallen |
|---|---|
| Berichtframing | Onvolledige JSON, meerdere berichten per TCP-segment, null-bytes in berichten |
| Groottelimieten | Enkele berichten van 10MB+, 10K+ newline-tekens in JSON-waarden |
| Codering | Unicode-BOM-prefix, CRLF-injectie, chunked encoding in JSON |
| SSE-parsing | Events zonder dataveld, ingebedde newlines in data, event-ID-injectie, retry-manipulatie naar 0 |
| Protocolverwarring | SSE-eventtype ingesteld op "error" met reconnect-URL die naar de aanvaller wijst |
Hardingschecklist
- Draai MCP-servers in aparte PID- en mount-naamruimten
- Beperk de rechten op
/proc/<pid>/fd/ - Onderteken JSON-RPC-berichten met HMAC, zelfs over stdio
- Waarschuw bij onverwachte schrijfacties naar de stdin van de server
- Vereis wederzijdse TLS voor alle verbindingen
- Bind sessies aan de fingerprints van het TLS-certificaat van de client
- Onderteken individuele JSON-RPC-berichten binnen de stream
- Wijs SSE-reconnecties van verschillende bron-IP's af
- Schakel HTTP/1.1 uit om CL/TE-smuggling te voorkomen
- TLS 1.3 voor alle HTTP-transporten
- Certificate pinning in de clientconfiguratie
- Netwerksegmentatie voor MCP-verkeer
- Zet IDS-regels in voor MCP-protocolanomalieën
- Per-sessie- en per-IP-ratelimieten op transportniveau
Een MCP-server wordt gestart met 'mcp-server | tee /var/log/mcp.log'. Wat is het primaire beveiligingsrisico?
Verwante onderwerpen
- MCP Tool Surface Exploitation -- MCP-aanvallen op protocolniveau die transportaanvallen aanvullen
- Agent Exploitation -- Bredere aanvalsoppervlakken van agents voorbij het transport
- AI Infrastructure Exploitation -- Aanvallen op infrastructuurniveau op endpoints voor modelserving
- AI Application Security -- Webapplicatie-aanvallen die overlappen met HTTP-smuggling
Referenties
- Model Context Protocol Transport Specification (2025)
- Kettle, "HTTP Desync Attacks: Request Smuggling Reborn" (PortSwigger, 2019)
- Kettle, "HTTP/2: The Sequel Is Always Worse" (PortSwigger, 2021)
- NIST SP 800-52 Rev. 2, "Guidelines for TLS Implementations"
- CWE-444: Inconsistent Interpretation of HTTP Requests