MCP request tampering¶
MCP request resource URI tool arguments 35–45 minutes
Most MCP exercises pause what a server tells a client. This one pauses what the client asks before the server sees it. Request and response control have different owners, proof sources, and mitigations.
| Recipe | Resource variant | Tool variant |
|---|---|---|
| Pause | resources/read request |
tools/call request |
| Attack | substitute /params/uri |
rewrite /params/arguments/account |
| Control | change /params/_meta/label |
change unused /params/arguments/note |
| Proof | MCP resource receipt | MCP call receipt + effect ledger |
forms request AIT
rewrites request MCP server
parses request Server
receipt Effect
ledger
Start the request-side lab¶
Two requests pause in sequence. Forward the first after completing its
observation so the workflow can reach the second. The break conditions target
resources/read and tools/call; breaking every MCP request would stop the
initialize handshake before the exercise begins.
Variant A: resource URI substitution¶
- Select the pending
resources/readrequest. - Confirm
/params/uriispolicy://approval/guidance. - Replace it with the alternate controlled resource shown by the lab.
- Mark the message as attack and forward it.
- Inspect the MCP server's resource receipt and returned resource identity.
For the close control, trigger again and change /params/_meta/label without
changing the URI. Both requests are modified, but only one changes which
resource the server is asked to return.
Variant B: tool-argument substitution¶
- Continue until the
tools/callrequest pauses. - Change
/params/arguments/accountto the alternate controlled account. - Forward the modified request.
- Inspect the server call receipt and effect ledger.
For the control, change /params/arguments/note, which the deterministic policy
does not read. Keep account substitution and resource substitution as separate
attack/control pairs.
Read the two proof chains¶
| Chain | Receiver evidence | Out-of-band effect |
|---|---|---|
| URI substitution | server receipt names alternate URI | returned resource corresponds to that URI |
| account substitution | server receipt names alternate account | effect ledger records that account |
Because the server will act on any valid request it receives, “the server did something different” is expected after an argument edit. The close control separates an authority-bearing argument from an adjacent irrelevant one.
Why the request side stands alone¶
Response tampering asks whether a client trusts what it is told. Request tampering asks whether a server trusts what it is asked. Authentic responses do not protect a request that changed in path; strict server argument validation does not protect a client from poisoned discovery that made it choose the wrong argument in the first place.
Evidence boundary¶
This exercise proves the controlled server received and acted on the delivered request. A production test must define safe resource and account substitutes in advance. Do not redirect a request to a resource or account outside the written scope merely because the protocol permits the value.
Done when¶
You can distinguish the resource and tool variants, show the server-side
receipt for each, and explain why _meta.label or note is a close control
rather than a second attack.
Next: MCP resource-content poisoning keeps the URI fixed and changes the content returned for it.