Ten of eleven bad tokens got past my agent gateway's verifiers. IBM's MCP gateway shipped the same class of bug.
Hey 👋
On 11 November I ran seventeen test tokens through the three services that verify my agent gateway’s principal token. Each token was correct except for one claim. Eleven should have been rejected. Ten got through at least one service. One accepted a token signed with the wrong algorithm. Another accepted a token whose issuer was the string "evil".
The day after, IBM published two CVEs for its ContextForge MCP gateway. One is a request header that overrides the credential the gateway is supposed to own. The other is an identity signature that can be replayed. AWS had patched an SSRF in its own MCP gateway registry on the 11th.
So this issue is about the gateway. It is the component every agent call passes through, and it’s where trust is supposed to be checked. Three of them, mine included, got that check partly wrong. OWASP’s new agentic guide, out the same week, sets the bar they missed: a control only counts if it sees the action before the action takes effect.
From the lab
When a pre-tool hook crashes, CrewAI and the Claude Agent SDK run the tool anyway (14 November). I put a policy hook in front of a tool in five agent frameworks, then made the hook throw and then hang. In CrewAI, and by default in the Claude Agent SDK, a hook that throws lets the tool run. LangChain middleware, the OpenAI Agents SDK and the MCP Python SDK failed closed. The post has the source lines and a fix for each. Tests: agent-hook-failure-tests. I’ve also asked CrewAI for an opt-in fail-closed mode (#9434).
Agent identity at the IETF: the finished parts are general OAuth, the agent parts are drafts (13 November). I sorted every document the IETF’s agent identity framework depends on by maturity. Everything finished is ordinary OAuth and HTTP. Everything written for agents is still a draft. Includes the -01 revision from 2 November and five things to build on now.
This week in AI security
OWASP’s agentic guide V2: if a guardrail can’t see the tool call, it doesn’t count
On 10 November the OWASP GenAI Security Project published Securing Agentic Applications V2, a 106-page guide for builders and defenders (the cover says October 2026). The sentence I’d pin above every agent design review is in section 3.3.7: “A guardrail that cannot observe a tool call before it executes is documentation, not a defense.”
It defines 18 hook points, from sessionStart to skillUnload. When a hook can’t decide because of an error or a timeout, “the action must fail closed,” because “a hook that fails open can be bypassed by anyone able to make it fail.” Section 6.4.3 adds that tool definitions should be re-hashed “on every session start,” with no approval carried across sessions.
The guide doesn’t say which framework exposes which hook. It describes coverage only in aggregate, and names LangChain and LlamaIndex as observe-only. Which SDKs have which of the 18, and which let the call through when the hook fails, is left to you. I tested the most important one, the hook before a tool call, in five frameworks (see From the lab above).
IBM ContextForge: a header that swaps the gateway’s credential, and a signature you can replay
IBM published two security bulletins on 12 November for ContextForge MCP Gateway, versions 1.0.0 to 1.1.0. Both were reported by Wolfgang Kriesel and both are fixed in v1.1.1.
CVE-2026-110279 (CVSS 8.1) is the simpler one. The X-Upstream-Authorization request header “can override the gateway-managed upstream credential.” An authenticated user could call upstream MCP servers “with a different credential and bypass per-user permission and audit attribution.” The gateway was supposed to decide which credential goes upstream. A client could decide instead.
CVE-2026-110278 (CVSS 7.4) is the one that matches my test. ContextForge signs identity claims and forwards them to upstream MCP servers. IBM says an attacker could “replay identity propagation claims signatures or expose sensitive user identity information to third-party MCP servers due to static signature payloads and missing per-gateway configuration checks during tool invocation.” IBM doesn’t spell out what “static” means. My reading is that the signed payload didn’t change between calls, so a captured signature stayed valid for later ones.
In my own gateway, presenting the same token twice is accepted by design. The only thing that limits replay is a 60-second lifetime. One of my two downstream services didn’t enforce that lifetime, so it accepted a token with a one-hour lifetime thirty minutes after it was issued. That is the same failure: the signature checks out, and nothing ties it to this call or this moment.
So what: an MCP gateway that propagates identity is only as strict as the loosest service that verifies what it sends. A signature proves who issued the claims. Lifetime, audience, a unique ID and an issuer check are what stop someone else reusing them. Each upstream server has to check all of them, and in my test none of the downstream copies checked all of them.
If you can’t upgrade yet, IBM’s workarounds are to strip X-Upstream-Authorization at your reverse proxy for every MCP endpoint, and to set IDENTITY_PROPAGATION_ENABLED=false so no upstream server receives identity data. As of 14 November neither CVE had a GitHub advisory on the ContextForge repo, so Dependabot may not flag it for you.
AWS’s MCP gateway registry: the fix doesn’t clean up what’s already registered
AWS bulletin 2026-180-AWS (11 November) covers CVE-2026-125926 in mcp-gateway-registry, versions 1.0.3 to 1.34.0. A user allowed to register or modify a server “could configure an upstream address that caused the gateway to send requests to services on the deployment’s internal network.” In some cases the gateway returned the response. Version 1.35.0 validates upstream addresses, but AWS says it “leaves server configurations stored before the upgrade unchanged.” Upgrading doesn’t remove an internal address someone already registered. AWS asks you to review every registered upstream, check your logs from the affected period for unexpected registrations, and rotate the registry’s cloud role credentials if you can’t rule out misuse. The researcher is credited as novice-22. GHSA-fc39-fwh3-wv5r →
When the gateway itself is the attacker
I didn’t cover this in October and it belongs with the stories above. HiddenLayer (22 October) showed what a compromised LLM gateway or inference server can do to the coding agents behind it. It can add tool calls the model never made, then strip both the call and its result before the conversation goes back to the model. In one demo Codex had git as an approved prefix, so the injected git -c diff.external='sh -c "cat .env"' diff --no-index /dev/null .env ran with no prompt and returned the secrets. The gateway can also tell harnesses apart by their headers, and timing alone shows which commands are auto-approved. Approval rules are written against the command, and nothing in them checks that the model actually asked for it. A toolCallRequest hook in the OWASP sense would see the injected call. It couldn’t tell that the model never made it. The guide’s fallback for paths it can’t hook is the right one here: scoped credentials, egress controls and server-side authorization, none of which depend on the call being genuine. If your agents talk to models through LiteLLM or any other proxy, that proxy is inside the trust boundary of every one of them.
Attackers ran an open-source pentest agent against AWS
Arctic Wolf Labs published on 10 November what it saw from AntiFox, an open-source agentic penetration testing platform with a Chinese-language interface, forked from ARTEX 0.1.1 (BleepingComputer). Attackers ran it from Alibaba Cloud. In one intrusion they dropped an ASPX web shell on an exposed IIS server and parsed web.config for connection strings. Arctic Wolf says the exploited vulnerability “was not identified.” In AWS, the actor used valid IAM users and, in some cases, an assumed EC2 role, and cycled through several identities. One intrusion produced “hundreds of cross-service API requests within approximately half an hour” across IAM, S3, Lambda, Secrets Manager, KMS, EKS, Bedrock and more. Most were denied. Some weren’t, and in some cases the sequence ended in a successful GetSecretValue on a production secret. Where the first AWS key came from, Arctic Wolf says only “obtained through unknown means.”
The agent’s speed worked against the attacker as a detection signal. A human doing that enumeration spreads it over hours. An agent compresses it into one dense burst of List, Get and Describe calls from one IP, mostly failing. Arctic Wolf’s hunting advice follows from that: one source IP using several keys or roles in a short window, and a successful call sitting inside a burst of denials. The user agents in its pack are Boto3/1.43.125 and Botocore/1.43.125.
Do this: query CloudTrail for successful
GetSecretValuecalls in the last 30 days, then for each one check whether the same principal or source IP had more than a few dozenAccessDeniederrors in the hour around it. Separately, list which of your EC2 instances still allow IMDSv1 and which application configs hold long-term access keys. Amazon’s own advice to affected customers named both.
One-line updates
- CVE-2026-98432 (#34’s lead). As of 13 November Ubuntu marks 26.04, 24.04 and 22.04 LTS fixed. 20.04 is still “work in progress.” Ubuntu →
- LiteLLM published what it’s changing (30 October). Release approval now sits with an account tied to “a specific physical device in our office,” and any token-based activity by an owner account is set to raise an alert, target 15 November. Secret-scanning tickets will close only “when revocation is confirmed.” That is the step that failed in May.
What I’m building
The rest of the hook matrix. The other 17 OWASP hook points, starting with sub-agent and memory hooks, against the same five frameworks. If you maintain one of them and know how your hooks fail, reply and save me a test.
Tooling worth knowing
- Arctic Wolf’s AntiFox pack. API sequences, user agents, endpoint process chains, file patterns and IPs in one README. wolf-tools →
- ai-dfir-toolkit by Raymond DePalma: vendor-neutral Sigma, YARA and Suricata rules for compromised LLM apps, MCP servers and ML supply chains. I’ve read the repo, not run the rules.
- Agent Security Scorecard: my free self-assessment against the OWASP Agentic Top 10. About 12 minutes, no login. Score your agents →
One thing to check this week
Find every place a gateway-issued token gets verified, and read the verify call.
1
grep -rnE 'jwtVerify|jwt\.verify|jwt\.decode|decode_jwt|Validation::new' --include='*.ts' --include='*.js' --include='*.py' --include='*.rs' --include='*.go' .
For each hit, check four things are set explicitly: the expected issuer, the audience, a pinned algorithm list, and a maximum token age with a small clock tolerance. Library defaults usually leave at least one of these open. In my case the two downstream services between them missed three of the four. Audience was the only check every service made. The service with the shortest list is the real contract, whatever the gateway’s documentation says.
What I’m watching
→ Microsoft Ignite, 17 to 20 November. Microsoft’s pre-event material describes a registry of every agent in an organization, including shadow agents. I want to see whether that registry can revoke an agent or only list it.
→ ContextForge advisories on GitHub. Whether CVE-2026-110278 and -110279 get GHSAs, so the fix reaches people who rely on Dependabot rather than IBM bulletins.
→ LiteLLM’s 15 and 30 November targets. The owner-token alert and revocation-confirmed scanning. Both are the controls that would have caught the May key.
→ AntiFox v2.0. It’s still public on GitHub. Whether other teams report it, or a successor, against other clouds.
On Tuesday I publish the next identity piece: what MCP can name today (the user, the app, the workload) and why the agent isn’t on that list yet. The full write-up of the token test, with the seventeen vectors and the method to run them on your own gateway, follows on 27 November.
If you run an MCP gateway and you’ve checked how your upstream servers verify what it forwards, reply and tell me what you found. I read everything.
Cheers, Amine
If a colleague runs an MCP gateway or an LLM proxy in front of their agents, forward this to them.
Sources
- Securing Agentic Applications V2: A Builder & Defender’s Guide, OWASP GenAI Security Project, 10 November 2026 (sections 3.3.7 pp. 49–54, 6.4.3 p. 78)
- Security Bulletin: IBM ContextForge MCP Gateway is affected by an improper authentication vulnerability (CVE-2026-110279), IBM, 12 November 2026
- Security Bulletin: IBM ContextForge MCP Gateway is affected by an information exposure vulnerability (CVE-2026-110278), IBM, 12 November 2026
- Server-side request forgery in the server registration and update API in mcp-gateway-registry (2026-180-AWS), AWS, 11 November 2026
- Man-in-the-Model: hijacking coding agents in transit, HiddenLayer, 22 October 2026
- Antifox agentic pentesting platform used to steal AWS credentials and move laterally, Arctic Wolf Labs, 10 November 2026
- Hackers use AntiFox AI agents in AWS credential-theft attacks, BleepingComputer, 11 November 2026
- What we are changing after October 21, LiteLLM, 30 October 2026
- CVE-2026-98432, Ubuntu Security, page last updated 13 November 2026