Infrastructure-as-Code Security

  • Link11-Team
  • April 12, 2024

Content

Infrastructure-as-Code Security

In the cloud-first world, infrastructure as code (IaC) has become a key part of software development and deployment. IaC allows engineering teams to manage their cloud infrastructure in a repeatable, consistent way. Unfortunately, when it comes to security, too often the focus stays on the application itself, with little attention paid to IaC code.

Organizations that want to stay secure in a modern, cloud-focused ecosystem should consider their IaC configurations to be first-class security concerns. Simply put, IaC is an important part of building security into your infrastructure.

In this article, we’ll look at how infrastructure as code functions, some potential attack vectors, and what can be done to secure your cloud environment.

Infrastructure as Code: A Primer

Historically, infrastructure as code has been used to describe a variety of different implementation choices. Tools like CFEngine, Puppet, and Chef are no doubt familiar to early adopters of IaC. Configuration management offered ease of use when managing fleets of servers at scale, but it was often bootstrapped onto already deployed infrastructure.

What Is It?

Modern IaC solutions like Terraform and CloudFormation automate the configuration, deployment, and management of infrastructure end to end. Users of IaC create resource configurations to define what infrastructure they would like deployed for a given provider. These tools generally share some common features:

  • A domain-specific language (DSL): In contrast to general-purpose programming languages like Python, DSLs are languages that are used in a specific application context. A DSL typically offers some kind of binary or compiler through which you can run a variety of commands.
  • State management: To manage infrastructure in a cohesive fashion, IaC tools need to maintain a persistent state representation, typically a large text file or database containing a complete data object representation of the currently managed resources.
  • Interface or proxy for provider APIs: One of the most powerful features IaC offers is the abstraction it creates between providers and resource configurations. Users of IaC tools like Terraform don’t need to implement direct API calls to GCP or AWS, because the provider logic is handled via plugin.
  • Declarative: The declarative paradigm no longer dominates the IaC landscape. Newer tools have given developers the ability to write using imperative patterns.

When using declarative languages, users “declare” the desired end-state of the infrastructure defined in the configuration, and the compiler will automatically decide the best path for achieving that state. In contrast, imperative programming models depend on the user to define program flow.

With tools like Pulumi and AWS CDK, users can simply import a library into their application code and provision infrastructure as they might create a standard application using an imperative language. It’s important to note that even while using these imperative tools, the underlying logic generally still behaves in a declarative fashion.

Usage Patterns

In smaller and less complex environments, IaC is typically managed by one or two engineers working from individual workstations. They may employ some standard conventions of scale, like shared state, but the scope of the infrastructure is handled easily by a small team or individual.

At scale, IaC usage typically involves multiple instances of shared state, isolated workspaces, multiple engineering teams across the organization contributing to configuration, and automated deployment via CI/CD. Changes are ideally analyzed for potential issues, and testing gives feedback on the potential impact of proposed changes.

Testing also highlights a larger theme here: As IaC usage grows in scale within an organization, more and more systems and data stores fall under its management purview. Given this broad power to effect change, IaC and related systems make for a very inviting target for threat actors.

Vulnerabilities in Infrastructure as Code

Infrastructure itself has always been a fundamental attack vector for cybercriminals. In the modern cloud era, the potential attack surface for an organization’s digital architecture has grown exponentially.

Infrastructure-as-code vulnerabilities typically fall into some common categories, and they’re almost always critical due to the potential blast-radius.

Credential/Secret Value Disclosure

Like other code, IaC configuration is likely to end up in some form of version control system (VCS) like Git. Most organizations make use of a third-party VCS platform such as GitHub for storing their repositories. The public nature of these platforms means that any sensitive values that inadvertently make it into a pushed commit are potentially at risk for public exposure.

With an IaC tool like Terraform, you can configure the AWS provider plugin using the following block of code:

# Configure the AWS Provider

provider “aws” {

region = “us-east-1”

}

While this seems innocuous, it’s also possible to configure it with credentials hardcoded:

# Configure the AWS Provider

provider “aws” {

region = “us-east-1”

access_key = “my-access-key”

secret_key = “my-secret-key”

}

If those values were populated and that configuration committed to a remote repository, it would be exposed to anyone with access. This is especially dangerous given the broad permissions typically issued to these identities.

AWS CDK has another example with its “Credentials” class. Sensitive values are typically handled using the SecretsManager API, but it is perfectly possible for a developer to hardcode a sensitive value using this static method. Although it may seem obvious that this should not be done, these types of secret disclosures often happen when a test or development mock-up was never fully ported to a production-ready implementation.

Most IaC tools have features that help users explicitly define sensitive values so they do not appear in logs or other outputs. However, these values are often persisted in state as plaintext. If secret values are provisioned in something like Vault with Terraform, the scope of control of those secrets will grow beyond Vault itself.

Misconfiguration

Misconfiguration of infrastructure can generally cause two distinct but negative outcomes. The first is that the security configuration of a given resource may be unexpectedly changed to a less secure posture. A classic example is Amazon S3 buckets, with sensitive data being configured to allow public access.

The second type of misconfiguration will often be the result of environments in which there is little to no change management or testing procedures in place.

A bad configuration can result in outages and impact customer-facing services.

Elevated Privileges

As alluded to in the previous section on credential disclosure, elevated privilege access is a serious concern for IaC tooling. IaC automation often assumes very high-privilege identity roles inside a given provider to provision infrastructure. If these identities are compromised through something like credential disclosure, attackers potentially have unlimited access to critical data and systems.

CI/CD Infrastructure

Continuous integration/continuous delivery (CI/CD) systems are the central pillar of DevOps and deployment automation. They’re often the mechanism through which IaC changes happen at scale in larger organizations.

The architecture of CI/CD pipelines is often complex, with several nodes, APIs, and some form of UI integrated. More complexity means more potential attack vectors. Broader industry recognition of the threats posed by insecure CI/CD systems has brought renewed focus on and the creation of an ecosystem of security tooling and education.

Securing Infrastructure as Code

To maintain a strong security posture, software organizations must apply the same secure development practices to IaC that they would to standard software development. The risk posed by lax IaC security practices is simply too great.

In addition to its excellent library of security reference material, OWASP has added a cheat sheet for securing infrastructure as code. Fortunately, there are some mitigations and practices that help to significantly reduce the risk of IaC vulnerability exploitation.

Use Static Analysis Tooling

Static analysis or static application security testing (SAST) tools are typically employed to analyze source code for potential vulnerabilities. In the case of IaC tools, you can use a specific subset of SAST tools to identify potentially sensitive values that may be present in the source code. Tools like TruffleHog proactively scan existing repositories and can even integrate with pre-commit hooks to ensure secrets never make it into local or remote Git logs.

Leverage a Policy Engine

Policy engines and policy-based controls like OPA allow administrators to define granular, declarative policies for a variety of system and infrastructure components. Using a DSL, you can define these policies to prevent security misconfigurations or potentially destructive changes from ever being applied to live infrastructure. Policies can be enforced locally via Git hooks or at scale via a policy engine API security deployment.

Log Critical Identity Activity

As mentioned previously, the identity that an IaC automation assumes will often possess very broad and permissive access to a variety of provider APIs. With that in mind, it’s crucial to closely monitor the API calls and behavior that identity engages in at all times.

Most providers give users access to several logging mechanisms, including logs of what API calls are made by different identities in the account. AWS CloudTrail is one such tool. These logs can be streamed into a third-party SIEM solution you can then use to analyze the logs for suspicious behavior and alert security operations teams if any is detected.

Secure Your CI/CD Pipeline

CI/CD systems are no different than any other infrastructure, and they should be subject to the same security rigor as application hosts. Self-hosted CI/CD architecture should occupy its own isolated network segment, with role-based access controls (RBAC) enforced across the board. You should closely monitor the logs for these systems for suspicious or unexpected behavior. Actively monitoring the CVE list can help identify potential components or systems that may have a vulnerability as well.

CI/CD also introduces unique security challenges, such as the potential for inadvertently exposing build artifacts. The major cloud providers all provide tools to help with this; we surveyed them in a previous article on securing CI/CD pipelines in the cloud.

Security Is Critical for Infrastructure as Code

Automatically mitigating potential infrastructure vulnerabilities is an important part of shifting security left in the SDLC.

Infrastructure as code makes managing cloud infrastructure much easier at scale. However, it also brings additional security challenges. Organizations must address these challenges through a combination of tooling, processes, and education. With the right cloud security measures in place, you will lessen your security risk significantly.

Rather than treating it as an afterthought, companies need to apply the same rigor and diligence to securing their infrastructure code as they do their application code.

20 Years of DDoS – a Brief Look at the Past and what the Future will Bring
DoS, DDoS und RDoS – What is the difference?
X