Threats
Jul 23, 2026
9
min read

Terraform Providers - The Overlooked Supply Chain Attack Vector

Brad Cheezum

Terraform is one of the most widely used Infrastructure as Code (IaC) tools leveraged by over 75% of companies to manage their cloud infrastructure. Because Terraform has official support for all of the major cloud providers, and community support for hundreds of others, it’s no surprise that it has been so broadly adopted. Within the same Terraform project you can spin up a full production environment across all three major cloud vendors and then order a pizza.

Hashicorp, the creators of Terraform, have over 22,000 modules and nearly 7,000 total providers in the Terraform Registry at the time of writing. These resources allow developers to quickly create infrastructure that follows best practices without needing to duplicate code in every project.

The Supply Chain Is Having a Moment

Supply chain attacks are hardly new, but they have become an increasingly attractive way to compromise organizations at scale. Instead of attacking each target directly, an attacker compromises something those targets already trust: a software dependency, package maintainer, build pipeline, update mechanism, vendor, or service provider.

The appeal is blast radius. One stolen publishing token, poisoned package, or compromised release process can distribute malicious code to thousands of downstream environments through entirely legitimate channels. The resulting activity may arrive signed, come from an approved domain, and execute with the permissions intentionally granted to trusted software.

In the first half of 2026 alone there have been numerous high profile and wide reaching campaigns targeting popular software vendors such as Trivy, LiteLLM, Checkmarx, and dozens of others. Given the risk, it is unsurprisingly a major focus across many enterprises to secure the supply chain. However, few companies consider Terraform a supply chain risk because they look at it as only a template to create resources, not execute code directly.

A Few Lines of Terraform, a Lot of Trust

Terraform modules are popular for the same reason software libraries are popular: they let teams reuse proven patterns instead of rebuilding common infrastructure from scratch. A few lines of configuration can create an entire network, Kubernetes cluster, database platform, or security baseline. Modules improve consistency, reduce development time, and allow teams to benefit from the work of experienced maintainers.

The Terraform Registry makes that reuse especially easy. Modules are searchable, versioned, documented, and can be referenced directly from any Terraform configuration:

module "example" {
  source  = "publisher/module/provider"
  version = "1.2.3"
}

That simplicity can create a false sense of safety. The Terraform Registry is a discovery and distribution mechanism, not a guarantee that every module is secure, well maintained, or limited to the behavior described in its documentation.

Using a module means trusting its source code, its maintainers, its dependencies, and the repository and release process used to distribute it. The risk is amplified by the context in which Terraform runs. Terraform commonly has very privileged credentials capable of creating and modifying infrastructure, reading secrets, and changing identity policies.. A malicious or compromised module may therefore execute with substantially more access than a typical application dependency.

Anyone can publish a module to the Terraform Registry with minimal requirements and no validation that the module isn’t malicious. The most popular module in the Registry has over 380 million downloads, looks official, but is actually managed by one individual who is thankfully not malicious and is doing a wonderful job.

Consider the following example. The “local-exec” command is undoubtedly malicious but Terraform’s safety net, terraform plan, doesn’t show the actual command that would be executed. While this plan only has a single resource, imagine a module with dozens of legitimate resources and one malicious one. Without reviewing the module’s source code directly it’d be easy to miss.

Figure 1. A malicious Terraform resource
Figure 1. A malicious Terraform resource
Figure 2. Terraform Plan output
Figure 2. Terraform Plan output

While this example is a destructive action it could just as easily be a credential harvester like the one used in TeamPCP’s attacks which allowed them to further exploit additional companies.

The Plan Is Not the Execution Boundary

Terraform’s provider ecosystem extends far beyond the major cloud platforms. Community providers exist for everything from security appliances and monitoring tools to niche SaaS products, local utilities, and internal APIs. That breadth is one of Terraform’s strengths: almost any system with an API can be incorporated into the same declarative workflow.

It also creates a more dangerous trust boundary.

A provider is not merely a collection of Terraform definitions. It is executable code downloaded to the system running Terraform and launched as a separate process. It therefore runs with the permissions, network access, environment variables, and credentials available to that Terraform process.

More importantly, a provider’s behavior is not limited to the resource changes displayed in a Terraform “plan” or “apply”. A malicious provider can read files, inspect environment variables, access cloud credentials, make outbound network requests, or execute any other arbitrary code without any of it showing in any of the output at all.

In fact, a malicious provider doesn’t even require resources to be created via “terraform apply” to be dangerous. Simply running “terraform init” is enough for a malicious provider to execute a payload.

Just like Terraform modules, anyone can publish a community provider under their own namespace. A listing in the Terraform Registry makes a provider easy to discover and install, but it does not make the provider trustworthy. Installing one should be treated much closer to downloading and executing a third-party binary than importing a passive configuration library.

A Terraform provider plugin is a compiled binary written in Go and there are no restrictions on what the binary can do. Below is an example of a “malicious” provider that executes a shell command.

Figure 3. A malicious command inside a Terraform provider
Figure 3. A malicious command inside a Terraform provider

When the malicious provider is included in a Terraform project, and the “terraform init” command is run, the payload executes silently.

Figure 4. Malicious provider configuration
Figure 4. Malicious provider configuration
Figure 5. Malicious payload execution during terraform initialization
Figure 5. Malicious payload execution during terraform initialization

The Shell Game

Modules and providers become more concerning when they are combined.

Terraform’s recommended pattern is for the root configuration to define provider configurations and pass them into child modules. However, a module can still contain its own “provider” block and declare a dependency on a provider the caller did not knowingly select.

That creates a useful hiding place for attackers. A developer may review the module’s inputs, outputs, and planned resources without noticing that it also causes Terraform to download and execute an unfamiliar provider binary. The module appears to be reusable infrastructure code, while the actual danger is embedded in an otherwise harmless looking module.

This is especially easy to overlook when the module otherwise behaves as expected. It may create the advertised resources, produce a reasonable plan, and have no suspicious output. Meanwhile, its bundled provider can execute arbitrary code with the permissions and credentials available to Terraform.

The important distinction is that a module is configuration, but a provider is an executable. When a module silently introduces its own provider, reviewing only the visible infrastructure changes misses the part of the dependency chain with the greatest ability to act outside Terraform’s model.

Below we have an example of an AWS Terraform project that uses a module. The provider is defined inside of the root configuration and the module inherits the provider definition.

Figure 6. Root Terraform configuration that includes a module
Figure 6. Root Terraform configuration that includes a module

However, inside of the module hides an additional, malicious, provider block that coexists with the otherwise harmless Terraform resources.

Figure 7. Malicious provider block hiding inside of a module
Figure 7. Malicious provider block hiding inside of a module

When “terraform init” and “terraform apply” are run the *only* indication of the malicious provider is in the Terraform initialization output. With a sufficiently convincing provider name this output would be easy to miss.

Figure 8. Malicious provider payload executes without any indication
Figure 8. Malicious provider payload executes without any indication

Borrowed History, Borrowed Trust

A malicious provider repository doesn’t need to be new or obviously suspicious. An attacker can clone a legitimate open-source repository, change the Git remote to a repository they control, and push the existing history under a new name.

Because Git preserves the commit graph, the copied repository retains much of what reviewers use as shorthand for legitimacy: years of commits, familiar contributor names, release tags, documentation, issue references, and the appearance of an actively maintained project.

The result can look convincingly mature even though the new repository itself is attacker controlled. A reviewer browsing the commit history may see reputable contributors and a long development timeline without realizing that none of those people created, reviewed, or endorsed the attacker’s copy.

The attacker only needs to add a small number of new commits containing the malicious behavior. Those changes can be buried at the end of an otherwise authentic-looking history, surrounded by thousands of legitimate commits inherited from the original project.

This is not a flaw in Git, distributed version control is designed to let repositories be copied while preserving their history. The problem is treating inherited history as proof of repository ownership or maintainer trust. Commit history can show where code came from, but by itself it does not prove who controls the repository distributing it now.

With some creative typo-squatting it’s possible to make a malicious repository almost indistinguishable from a legitimate repository with hundreds of commits spanning nearly a decade.

Figure 9. A malicious repository disguised as the legitimate repository
Figure 9. A malicious repository disguised as the legitimate repository
Figure 10. The legitimate repository
Figure 10. The legitimate repository

This malicious module repository can then be published to the Terraform Registry appearing under a legitimate looking namespace.

We Scanned the Providers So You Don’t Have To

The obvious next question was whether any of this was purely theoretical.

To find out, we analyzed over 5,500 community Terraform providers for signs of malicious, deceptive, or otherwise high-risk behavior. The analysis combined static-analysis findings, source snippets, imports, dependencies, call graphs, file metadata, and targeted review by a large language model prompted to behave as a malware analyst rather than a general-purpose code reviewer.

The results were:

ClassificationProviders
Benign3,949
Suspicious1,091
Insufficient Evidence652
Further Review Required12
Malicious5

The five malicious providers appear to be proofs of concept demonstrating techniques such as credential collection, command execution, hidden network activity, or other behavior unrelated to the provider’s stated purpose. We did not find evidence that they were part of active campaigns, but they demonstrate that malicious providers are not merely hypothetical and that the Registry can already distribute code designed to abuse Terraform’s trust model.

The much larger suspicious category requires more context. Most of those providers made external network requests or performed other behavior that could be legitimate for their intended function but could not be confidently validated through automated analysis alone. A provider communicating with an API is normal. A provider communicating with an undocumented or unrelated destination is not. Distinguishing the two requires understanding what the provider claims to do, where it is expected to communicate, and what data it transmits.

The insufficient evidence category mainly included providers whose repositories had been deleted, contained little or no source code, relied primarily on precompiled binaries, or otherwise lacked enough material for a meaningful conclusion. Twelve additional providers contained findings significant enough to justify deeper manual review but not enough evidence to classify them as malicious.

The analysis deliberately ignored ordinary code-quality issues, dependency vulnerabilities, performance problems, and stylistic concerns. Its focus was narrow: credential theft, data exfiltration, command execution, backdoors, hidden behavior, unexpected network communication, persistence, obfuscation, and other supply-chain indicators.

The prompt also accounted for the normal behavior of Terraform providers. Reading environment variables, making HTTP requests, handling credentials, and interacting with remote APIs are not inherently suspicious. They became relevant only when the behavior appeared unnecessary, deceptive, excessive, or unrelated to the provider’s documented purpose.

That distinction matters. The goal was not to produce a list of providers that use “net/http” or “os.Getenv”. It was to identify providers whose behavior could not be reasonably explained by what they claimed to do.

The results do not suggest that the community provider ecosystem is broadly malicious. They do show that anyone consuming a provider is making a code-execution trust decision—and that the current ecosystem contains both intentionally malicious examples and a substantial number of providers whose behavior deserves closer scrutiny.

Ready to Reduce Cloud Security Noise and Act Faster?

Discover the power of Averlon’s AI-driven insights. Identify and prioritize real threats faster and drive a swift, targeted response to regain control of your cloud. Shrink the time to resolution for critical risk by up to 90%.

CTA image