It was not long ago when we needed to submit an IT support ticket to help launch infrastructure configurations (virtual machines, networks configurations, load balancers, databases, etc.) every time we needed to deploy a new application. It worked when we needed those less frequently, but it was not easily scalable. And you might remember the reproducibility hassles as well: “This application worked on my system, but how is it failing on yours?”
Fast forward to today and our era of cloud environments and infrastructure as code (IaC). The cloud computing environment has made it easy to deploy and manage a more dynamically provisioned infrastructure, but you still need to click a few buttons to adjust those provisioned infrastructure instances as needed. The concept of IaC came into practice to simplify the process of provisioning and managing infrastructure for cloud environments. IaC made it feasible to provision infrastructure in a consistent, scalable, and reproducible manner for each deployment via human-readable configuration files.
IaC is descriptive code commonly written in either markup (JSON, YAML, etc.) or proprietary languages that describe the infrastructure resource configurations. These scripts are then used by IaC tools to automatically provision, update, or delete infrastructure resources on the fly while managing the dependencies between resources in a logical order.
IaC made it possible to write the desired state of the infrastructure as code. Thus, various versions and updates could be managed as code in an SCM environment and could directly be integrated into continuous deployments.
Some of the popular IaC tools from public cloud vendors are AWS CloudFormation, Azure Resource Manager, and Google Cloud Deployment Manager. Terraform by Hashicorp is cloud-agnostic and supports many cloud vendors.
IaC improves usability and functionality and helps shift the infrastructure deployment left, to the developers. However, if we put on a security hat, when usability and functionality go up, the potential causes of security issues also go up.
Figure 1 below is a very simple code snippet creating an AWS workspace in an AWS CloudFormation template, written in JSON format, that sets the volume encryption of workspaces off. This is an obvious flaw that may lead to a security issue.
Figure 1: A code snippet created in AWS CloudFormation using JSON format, that sets the volume encryption of workspaces off.
An easy fix would be to set the RootVolumeEncryptionEnabled and UserVolumeEncryptionEnabled variables to true. This example seems like an obvious issue to take care of, but such mistakes frequently happen either accidentally or because of someone’s carelessness, and in some cases, such flaws are only discovered after they have been exploited.
So the question is: what are some best practices to follow, and how can we ensure that these configurations are secure?
The principle of least privileges is a good place to start: restrict user account access to only what is essential for the desired function. Avoid using default configurations, and ensure the encryption of data storage, the security of network configurations and segmentations, and the proper encryption and management of secrets. Data should always be encrypted—not only at rest but also in transit. If secrets are exposed, it may allow unwanted access to sensitive data. Similarly, properly segmented networks can help ensure that resources and related dependencies are securely configured, thus helping to contain any potential damage from unwanted actors getting access to the network and databases.
One major advantage of IaC is that it helps prevent infrastructure security issues from going into deployment. It enables organizations to enforce security in IaC configurations alongside other automated application security testing in developers’ IDE and the CI/CD pipeline.
Like testing software code for security flaws using SAST, SCA, etc., there are specific tools designed to test IaC configurations for potential security flaws. Organizations can also set specific policies to be enforced in IaC deployments, and block any changes that don’t follow those policies.
The recently announced Rapid Scan SAST capability from Synopsys (powered by the Sigma analysis engine) is designed to help organizations detect and fix potential security flaws in their IaC deployments along with the software code, early in the life cycle.
Rapid Scan SAST is designed to provide lightning-fast results as developers are coding, in their IDE, and it can be easily integrated into CI platforms for scans during CI builds. Along with identifying IaC security flaws, Rapid Scan SAST also looks for API misuses and vulnerable configurations in the software code and provides developers with actionable findings. Rapid Scan SAST currently supports scanning for Terraform, AWS CloudFormation, and Kubernetes IaC files. It provides support for GitHub Actions and GitLab CI for scan automation and issue management, as well as for multiple analysis output formats (SARIF, JSON, or console). It will be available in the Code Sight™ IDE plugin for Visual Studio Code later this month, to help developers find and fix issues as they are coding.
Figure 2 is an example of an AWS relational database instance deployment YAML file in the vulnerable-by-design open source KaiMonkey project. The database is publicly accessible, and Rapid Scan SAST flags it as a critical issue.
The Code Sight IDE plugin is easy to use for developers. The left pane in Figure 2 shows a list of the issues found during a scan. When you select an issue, it displays the code and the line and location where the issue is present, and a brief description. You can see the detailed description, remediation advice, and options to dismiss the issue when hovering the cursor over it, or take appropriate action as you are writing the code.
Figure 2: Code Sight IDE plugin flags an issue and the location where it appears in the code.
Similarly, once you configure GitHub Actions to run Rapid Scan SAST and upload the analysis results, you can view them in the GitHub Security dashboard. Figure 3 below is an example of the same issue shown in Figure 2, as seen in the GitHub dashboard. It highlights the line and location where the issue is found, flags the issue as “Error” (translating to High or Critical severity issue), and provides a brief description of the issue and fix recommendation.
Figure 3: GitHub dashboard highlights the line and location of the flagged issue.