Top/Articles/Terraform MCP Server: Others Can Act With Your Token (CVE-2026-16498)
terraform-mcp-server-cve-cover-en

Terraform MCP Server: Others Can Act With Your Token (CVE-2026-16498)

HashiCorp's official Terraform MCP server had three flaws letting one user act with another's credentials. CVE-2026-16498 scores 10.0. Fixed in 1.1.0.

NewsPublished July 29, 2026 Updated today
Table of contents
Key takeaways

HashiCorp's official Terraform MCP server had three flaws letting one user act with another's credentials. CVE-2026-16498 scores 10.0. Fixed in 1.1.0.

On July 28, 2026, HashiCorp published security bulletin HCSEC-2026-23. It covers three vulnerabilities in "terraform-mcp-server," the official program that lets an AI assistant operate Terraform (the tool that manages servers and networks through configuration files).

The worst of them, CVE-2026-16498, carries a CVSS score of 10.0 β€” the maximum. The Terraform token supplied by one user could end up being used for the requests of whoever connected next. Your action runs with someone else's permissions, or someone else's action runs with yours. In short, the question of "whose credentials is this running as" stopped having a reliable answer.

On the same day, GitHub's official MCP server, "github-mcp-server," also received CVE-2026-47427 (CVSS 7.5). That one is not about credentials: a single malformed request kills the server process.

Here is the conclusion up front. None of these four affect you if you run an MCP server locally on your own machine, by yourself, over the stdio transport. The exposure comes from running an HTTP listener so a team can share the server. HashiCorp's deployment documentation states that the default transport is stdio, which puts the majority of individual users out of scope. Below is which configurations are affected and what to do, built only from primary sources.

The four vulnerabilities

Every number below was assigned by the vendor that filed the CVE (HashiCorp and GitHub). The US National Vulnerability Database has not finished its own analysis for any of the four β€” all are still in "Received" status with no machine-readable product definitions attached. In other words, the 10.0 and the 8.9 you are seeing are vendor self-scores, not third-party verified figures.

CVEProductCVSSWhat happensClassFixed in
CVE-2026-16498terraform-
mcp-server
10.0
(CRITICAL)
In stateless HTTP
mode, one user's
token is reused
for the next
user's calls
CWE-488
(data exposed to
wrong session)
1.1.0
CVE-2026-16496terraform-
mcp-server
8.9
(HIGH)
In stateful HTTP
mode, holding
someone's session
ID lets you act
with their
credentials
CWE-384
(session fixation)
1.1.0
CVE-2026-14869terraform-
mcp-server
8.6
(HIGH)
The destination
address can be
swapped, sending
the server's token
to an attacker
CWE-918
(SSRF)
1.1.0
CVE-2026-47427github-
mcp-server
7.5
(HIGH)
A single request
with a missing
field kills the
process
CWE-476
(NULL deref)
1.1.0

Both fixed versions being numbered "1.1.0" is a fact. But terraform-mcp-server and github-mcp-server are separate projects maintained by separate organizations, with different CVEs and different reporters. The matching version numbers are a coincidence, and there is no information anywhere suggesting a shared root cause.

This pays off for whoever can already reach that shared server

For the three terraform-mcp-server issues, the person who benefits is less a distant professional crew and more anyone who can already reach that shared MCP server. Someone from another team at the same company, a contractor with temporary access, or a departing employee whose connection details still work. And if that HTTP listener is reachable from the internet, add anyone who finds the URL β€” for CVE-2026-14869, HashiCorp's bulletin states outright that no authentication is required.

Entry is the MCP listener; the exits are your workspaces and variables. All anyone has to do in between is push Terraform operations through while wearing someone else's credentials. List workspaces they should not be able to see, read the values of variables, and change them if the token allows it. CVE-2026-14869 works one step differently: it rewrites the destination of the traffic the server was going to send to Terraform, delivering the attached authorization token straight to the attacker. The prize there is not someone else's session but the server's own key.

What you have wired behind those workspaces and variables is what decides how far this goes. HashiCorp's bulletin says an attacker could reach "the victim's Terraform organizations, workspaces, variables, and other resources within the scope of that token's permissions." Terraform variables commonly hold cloud access keys and database connection strings, so once those are read, the blast radius stops being Terraform-shaped. For the operations side there is a second problem: the identity recorded in the audit log no longer matches who actually did the work, so you lose the ability to trace who made a change. Remediation is "move to 1.1.0," but it is faster to first check whether your setup is even in scope, so let's go through that.

Is your setup in scope?

All three terraform-mcp-server issues require the "streamable-HTTP" transport to be enabled. For each of the three, HashiCorp's bulletin explicitly says deployments using stdio only are not affected. Better still, 16496 and 16498 are mutually exclusive β€” no single deployment hits both. Stateful (the default) means CVE-2026-16496; explicitly choosing stateless means CVE-2026-16498.

How you run itCVE-2026-16498CVE-2026-16496CVE-2026-14869What to do
stdio only
(default, single user)
Not affectedNot affectedNot affectedNo rush
(next update)
HTTP, stateful
(default when shared)
Not affectedAffectedAffectedMove to 1.1.0
HTTP, stateless
(explicitly set)
AffectedNot affectedAffectedMove to 1.1.0
first
HTTP reachable
from outside
Depends on modeDepends on modeAffected, no authUpdate and
restrict the listener

By version, it looks like this. There is one inconsistency here, which gets its own section further down.

ProductAffected versionsFixed inFix releasedLatest today
terraform-
mcp-server
Bulletin: 0.2.1–1.0.0
CVE record: 0.3.0
up to <1.1.0
1.1.0July 14, 20261.1.0
github-
mcp-server
<1.1.01.1.0May 28, 20261.7.0
(July 23)

On the github-mcp-server side, the fix shipped in 1.1.0 back in late May and the project has since moved on to 1.7.0. Judging by the release history, anyone keeping up with updates was already patched long before the CVE got a number.

The three terraform-mcp-server issues, one by one

CVE-2026-16498: the previous user's token gets used for the next one (CVSS 10.0)

HashiCorp's explanation runs like this. In stateless HTTP mode, the underlying MCP library does not assign unique session identifiers to requests. But the server looked up its cache of reusable Terraform API clients by session identifier. With the identifier effectively empty, everyone shared the same drawer, and the credentials supplied by one tenant were reused for the next tenant's request.

The weight of this one comes from needing no attack step at all. Nobody has to craft anything β€” it happens the moment two people meet on the same server. The CVSS vector is AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L: no privileges, no user interaction, and a scope change (S:C), which is the combination that reaches 10.0. The general availability announcement of June 11, 2026 described the shared-service deployment as one where "team members access remotely while maintaining individual access controls through their own Terraform tokens." This vulnerability is exactly that premise failing to hold.

HashiCorp's own internal team found this one; it was not an external report. In CISA's decision framework (SSVC), exploitation is recorded as "none" and automatability as "yes."

CVE-2026-16496: leak a session ID and someone rides your permissions (CVSS 8.9)

This is the stateful side. It caches a Terraform client per session, but the cache lookup key was the MCP session ID alone, and the cached client was never bound to the token that created it. Anyone who obtained another user's session ID could put it on their own request and have their calls executed with the victim's client and bearer token. Stateful is the default when the server is run centrally, so most "shared over HTTP" deployments land here.

This is the only one of the three reported externally: Juan Pablo Martinez Kuhn of Coinspect brought it to HashiCorp. The vector is AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:L. Attack complexity is High because getting hold of someone else's session ID is a prerequisite. HashiCorp's own workaround list includes "treat MCP session IDs as sensitive values," which is worth acting on before you upgrade: check whether session IDs are sitting in plaintext in your logs or proxy access records.

CVE-2026-14869: rewrite the destination, walk off with the token (CVSS 8.6)

This is the most attack-shaped of the three. terraform-mcp-server takes the Terraform endpoint address as configuration and talks to it using a server-side bearer token. The middleware handling incoming HTTP requests rejected a client-supplied address when it arrived as an HTTP header. But it did not apply the same check when the same value arrived as a URL query parameter. So an attacker sends a single request with their own address in the query string and has the server's authorization token delivered to them.

HashiCorp states plainly that exploitation required only the ability to send an HTTP request to the streamable-HTTP listener, with no authentication. If you exposed the listener to outside traffic, this is the most realistic threat of the set. The 1.1.0 changelog says client-supplied TFE_ADDRESS is now disabled outright in streamable-HTTP mode, with the address configured server-side only β€” the fix removes the very possibility of a client choosing the destination. Structurally this looks a lot like the mcp-grafana vulnerability, where credentials flowed out of an AI connector to an external endpoint.

GitHub's official MCP server: the "knock it over" kind

CVE-2026-47427: a request without ref kills the process (CVSS 7.5)

This one is not about credentials. In github-mcp-server, the CompletionsHandler in pkg/github/server.go accessed params.Ref without checking whether it was nil. Send a completion/complete request with the ref field missing and you get a Go runtime panic that takes the process with it. GitHub's advisory includes the actual request; an empty {} for params is enough to reproduce it. The reporter also documents fuzzing results: 108 crashes out of 925 test cases, an 11.7% crash rate.

The fix commit is tiny: three lines that return an error if req, req.Params, or req.Params.Ref is nil, plus 24 lines of tests. It merged on May 19, 2026 and shipped in 1.1.0.

From fix to CVE number

For all four, the fixed release was already out by the time the CVE became public. The github-mcp-server side has a disclosure trail recorded by the reporter, so that is included below.

← Swipe to move

The published information contradicts itself in three places

Cross-checking the primary sources turns up three spots where the numbers and the prose disagree. Here they are, so nobody over- or under-reads the risk.

First, the lower bound of the affected range. HashiCorp's bulletin says "terraform-mcp-server 0.2.1 up to and including 1.0.0," while the CVE record HashiCorp filed as the assigning authority says "0.3.0 up to but not including 1.1.0." The two disagree over whether 0.2.1 and the 0.2.x line are in scope, and because the bulletin caps at 1.0.0, the status of anything above 1.0.0 but below 1.1.0 is also hard to read. If you are on 0.2.1 or later, treating yourself as affected is the safe call.

Second, the prerequisite for CVE-2026-16496. The summary section of HashiCorp's bulletin says it "may allow an authenticated user to access another user's cached Terraform credentials," yet the CVSS vector is PR:N β€” no privileges required. Reading the detail section, the actual actor is "a user who obtained another user's session ID," and that prerequisite is what the High attack complexity (AC:H) accounts for. This is not something anyone can trivially try; it presupposes a session ID leak.

Third, how the maintainers rate CVE-2026-47427. The advisory and NVD text say any unauthenticated client able to send JSON-RPC can crash the server immediately, a complete denial of service, and the CVSS treats availability impact as maximum (A:H) for a 7.5. Meanwhile Pull Request #2502, which carried the fix, describes the impact as: for a local stdio server, "a malformed request would crash the process. Trust boundary is the spawning client, so impact is self-DoS"; for a remote server, "not reachable unauthenticated (PAT/token required), so at worst an authenticated caller self-crashes their own session." It closes with "still worth fixing as routine hardening." Same hole: the number says "unauthenticated total outage," the people who fixed it say "self-DoS." We cannot settle which is right, but before treating the 7.5 as an emergency, check whether your instance is actually reachable without authentication.

One more wrinkle: the body of GitHub's advisory page still carries the values from the time of reporting β€” "Affected versions: <= 0.33.0" and "Patched versions: None." The machine-readable data for the same advisory (the GitHub Advisory API) returns "<1.1.0 affected, fixed in 1.1.0." Your conclusion changes with where you read, so go with the machine-readable data and the NVD text.

Moving to 1.1.0 may require configuration changes

terraform-mcp-server 1.1.0 bundles two breaking changes along with the security fixes. Upgrading blind can break your deployment, so check these first. Both are spelled out in the changelog.

  • If clients were supplying TFE_ADDRESS (the endpoint address) via header or query parameter, 1.1.0 now returns 403. The address must be set server-side through the environment variable (this is the CVE-2026-14869 fix)
  • If you relied on X-Forwarded-For to carry the client IP through a proxy, the default has moved to the safer RemoteAddr, so you must now set MCP_REMOTE_IP_METHOD and MCP_XFF_TRUSTED_HOPS explicitly

1.1.0 also contains a security fix that never got a CVE: the organization allowlist validation and the downstream Terraform API request could end up using different tokens, which reads as a conflicting TFE_TOKEN header being able to bypass the allowlist. That, too, undermines the premise of shared operation, and following CVE numbers alone would have missed it. As with the Argo CD vulnerabilities, infrastructure tooling rewards reading the changelog directly.

HashiCorp's recommendation is phrased as "evaluate the risk associated with these issues and consider upgrading to 1.1.0" β€” noticeably restrained for a bulletin that includes a 10.0. If you cannot upgrade right away, the stated workarounds are restricting network access to the streamable-HTTP listener to trusted users only, and treating MCP session IDs as sensitive values.

No advisory from Japan's public bodies yet

We could not find any of these four in Japan's public vulnerability databases. Searching JVN iPedia, run by IPA and JPCERT/CC, for "terraform," "MCP," "HashiCorp" and each CVE number returned zero hits (checked July 29, 2026, 13:00 JST). Nothing appears in JPCERT/CC alerts or IPA's critical security notices either.

Japanese-language write-ups are likewise absent from what we could find on Hatena Bookmark and Zenn. There are Japanese articles on MCP server security in general, but none covering these four, so this may be the first Japanese-language breakdown. Terraform is a staple in Japanese infrastructure work, and this time the flaws are on the HashiCorp-official and GitHub-official side, not in some random third-party tool. Somebody inside a company standing up a shared server because it is convenient is an entirely plausible scenario.

On scale, honestly: terraform-mcp-server has roughly 1,480 GitHub stars, a small user base next to github-mcp-server's 31,800-plus. On top of that, only HTTP-shared deployments are affected, which narrows the population further. But for the organizations that do qualify, the very act of sharing means several people's Terraform permissions are exposed at once, and the numbers land on them in full.

Any sign of active attacks?

Not so far. Checking the US CISA catalog of vulnerabilities known to be exploited in the wild (KEV), none of the four appear among the 1,655 entries in catalog version 2026.07.27 β€” there are no HashiCorp entries at all. You can follow what is in KEV through our CISA KEV dashboard.

EPSS, which estimates the probability of exploitation, has no score for any of the four yet (queried through FIRST's API, no data returned). Given they went public a day ago, values should start appearing within days to a week. In CISA's SSVC framework, the three terraform-mcp-server issues are marked exploitation "none," while CVE-2026-47427 alone is "poc" β€” because the advisory text includes a reproducing request, not because attacks have been seen.

MCP servers ship as Go and Python packages and often arrive as part of a dependency tree, so sweeping your environment mechanically for stale versions β€” with something like an OSS supply chain scanner β€” is the faster path.

MCP servers keep failing the same way

What follows is the author's opinion. Read it separately from the facts above.

We have covered several MCP server vulnerabilities over the past year. mcp-pinot was open to anyone out of the box at CVSS 10.0; mcp-server-kubernetes leaked cluster admin credentials at 9.8; LiteLLM let commands through an MCP endpoint and ended up in CISA KEV; mcp-grafana leaked credentials outward. Line them up and the words for the cause differ but the landing spot is always the same: the authentication and authorization boundary has not been redrawn for the new MCP layer.

What the three new issues show, I think, is the next step of that problem. mcp-pinot and mcp-server-kubernetes were close to "we forgot to require authentication." terraform-mcp-server did have a design for taking a token per user and separating permissions β€” that part was thought through. And yet if you get the storage of "whose token was this" wrong, having an authentication design stops mattering. Using the session ID as a cache key looks like ordinary code, right up until it meets a mode that never issues session IDs and blends everyone's tokens together. Not a gap in the design, but a gap in how state was held.

And one more thing. MCP servers spread as a way to hand tools to an AI on your own machine, but "this is useful, let's share it with the team" happens naturally. At that moment, code written for a single user becomes a multi-tenant server. All three of the new issues are invisible in stdio operation and appear only once you share. Sharing an MCP server has, in practice, become as heavy a job as writing your own internal authentication proxy. If you are going to share one, plan on putting your own authentication and network controls in front of it.

What to settle before you move to 1.1.0

Start by checking whether you run terraform-mcp-server over streamable-HTTP at all. If it is stdio only, there is no urgency; picking up 1.1.0 at your next update is enough. If you run it over HTTP, move to 1.1.0, but review the breaking changes above (the TFE_ADDRESS handling and the X-Forwarded-For settings) first. If you cannot upgrade immediately, narrowing who can reach the listener is the workaround.

If you have been sharing over HTTP for any length of time, do not stop at upgrading. CVE-2026-16498 occurs in stateless mode with no attack at all, and CVE-2026-14869 needs no authentication. Treat the Terraform token held by the server as potentially disclosed and rotate it. It is also worth reviewing Terraform Cloud / Enterprise audit logs for workspace reads or variable accesses that do not match anything your team did.

On the github-mcp-server side, anything at 1.1.0 or later is already fixed, and the current release is 1.7.0. If you have environments stuck on the 0.x or 1.0.x line, they are behind on far more than CVE-2026-47427, and upgrading those is the higher priority.

βœ“ Confirmed facts

  • βœ“The three terraform-mcp-server issues were published July 28, 2026 as HCSEC-2026-23; the fix is 1.1.0 (HashiCorp bulletin)
  • βœ“Scores are 10.0 / 8.9 / 8.6 in order, all assigned by HashiCorp, with NVD's own analysis pending (NVD)
  • βœ“None of the three affect stdio-only deployments; 16496 affects stateful only, 16498 stateless only (per the bulletin's detail sections)
  • βœ“CVE-2026-16496 was reported by Juan Pablo Martinez Kuhn of Coinspect; the other two were found by a HashiCorp internal team (CVE record)
  • βœ“CVE-2026-47427 affects github-mcp-server below 1.1.0; the fix commit landed May 19, 2026 and 1.1.0 shipped May 28 (release)
  • βœ“None of the four are in CISA KEV (catalog 2026.07.27), and EPSS has no scores
  • βœ“No JVN iPedia entries for any of the four; no Japanese-language coverage found (as of July 29, 2026, 13:00 JST)

? Not yet confirmed

  • ?Real-world exploitation β€” no observations found for any of the four
  • ?Technical write-ups or PoCs for the three terraform-mcp-server issues β€” nothing published by the reporters or third parties
  • ?The lower bound of the affected range β€” the bulletin says 0.2.1, the CVE record says 0.3.0, with no clarification from HashiCorp
  • ?The real severity of CVE-2026-47427 β€” advisory says "unauthenticated total outage," the fix PR says "effectively self-DoS," and GitHub has issued no unified statement
  • ?How many organizations run terraform-mcp-server shared over HTTP β€” no published statistics

Sources

avatar-m-1

Makoto Horikawa

Backend Engineer / AWS / Django