Thanks to DevOps practices, enterprise IT is faster and more agile. Automation in the form of automated builds, tests, and releases plays a significant role in achieving those benefits and creates the foundation for Continuous Integration/Continuous Deployment (CI/CD) pipelines. However, is it possible to integrate security into the mix without slowing down the process? One way IT teams can integrate security into the DevOps pipeline is by making sure that released code is safe from the very start. The concept of integrating security as a first-class citizen into a DevOps process is known as DevSecOps, and is a best practice for security-sensitive businesses.
Cloud Academy recently released a new set of DevOps labs highlighting some best practices for automation in CI/CD pipelines. In this post, I’ll show you how you can use static analysis in CI/CD pipelines to improve the quality of your code to reduce issues now and in the future.
What is static analysis?
Static analysis is a method of analyzing code for defects, bugs, or security issues prior to pushing to production. Often referred to as “linters,” static analysis tools remove the unnecessary fluff from your code and perform some automated checks to improve code quality. Static analysis tools can check for:
- Inconsistencies in code style conventions and standards. It can be as simple as enforcing consistent indentation and variable names or as complex as enforcing compliance with the MISRA or CERT Secure Coding Standards
- Resource leaks such as a failure to release allocated memory, which can eventually lead to program crashes or failure to close files
- Incorrect usage of Application Programming Interfaces (APIs)
- Common security vulnerabilities such as those identified by the Open Web Application Security Project (OWASP) or Common Weakness Enumeration (CWE)
What kinds of static analysis tools are available?
The static analysis tools available can be categorized by the capabilities they support, including:
Real-time tools: Instantaneous analysis tools are ideal for checking code in development environments as it’s being written. Here, the tradeoff is speed over more thorough, time-consuming checks. Many of these are open source, which allows for easier adoption and customization.
Deep analysis tools: On the other end of the spectrum, deep analysis tools can take much longer and are likely to identify issues that a real-time tool would miss. Enterprise-grade tools in this area often have hefty licensing fees and they may bring more issues to light than you have the bandwidth to address. Many of these tools may be configured to report only the most important issues,.
Compilers: Although not a dedicated static analysis tool, compilers may also be used to improve the quality of your code. You can use configuration flags to adjust the number of checks they perform.
Integrating Static Analysis within CI/CD
Among the many benefits of using static analysis tools, the one that is most beneficial to organizations is the ability to discover bugs before they are released into the wild (and when they are less costly to fix). Within the DevOps practice of CI/CD, static analysis tools provide additional benefits.
Tools that take a long time to run tend to be ignored during development. Even if static analysis isn’t always a long process, it’s still not the best use of a developer’s time. Integrating analysis tools within CI/CD ensures that they are used consistently and automatically while offering an extra level of analysis to make sure that nothing is able to sneak through.
There are different options for how to integrate static analysis tools in your environment. One approach is to run it early in the pipeline along with other automated tests. At this point, you’ll be able to fix any issues before the peer code review and it speeds up the overall process. In turn, developers spend less time reviewing and have more time to develop new code.
If you have large code bases, running a deep analysis on every commit may take too much time. Instead, you can use a less thorough analysis configuration on development branches and perform more expensive scans on a schedule or when integrating into upstream branches. The goal is to discover bugs as early as practically possible and it’s up to you to choose the system that works best for your team. Tools like Klocwork have fully embraced CI/CD workflows and can incrementally analyze the code changes on each commit.
Higher-end static analysis tools can also track bugs over time. This can help you select which issues to work on in the current release cycle as source code is continuously being integrated. Issues reported in longstanding legacy code that haven’t caused problems are probably not worth the time investment to resolve them in the immediate term. Instead, use precious developer time to focus on more recent issues.
Another practical constraint is the budget available for static analysis. Rather than obtaining a license for each developer, run the analysis tools on a set number of build machines (or a single machine if possible).
You can experience how static analysis works in CI/CD by completing the Static Code Analysis within CI/CD Pipelines lab on Cloud Academy. This new Hands-on Lab uses an AWS-centric continuous deployment pipeline for deploying a Node.js application. The application is initially released to production without performing static analysis. You learn how to perform an injection attack on the deployed application and then use static analysis to identify the security issue. Finally, you integrate static analysis into the AWS CodeBuild build stage in the pipeline to prevent the vulnerable code from being deployed before you implement a fix. Here is the final environment:
Static Analysis of Infrastructure as Code within CI/CD
Infrastructure as code (IaC) offers many benefits to developers including no configuration drift, easily reproducible environments, and simplified collaboration with version control. Did you know that static analysis can also be used to enforce code standards and identify security vulnerabilities for your infrastructure? By using static analysis for infrastructure code, you automate the process and receive earlier feedback compared to infrastructure tests that require actually deploying the infrastructure, a potentially time-consuming operation.
There is usually some form of static analysis built in to most any IaC framework that you may be using. There may be commands to check syntax, ensure that valid parameter values are used, and automatically style the code. You may also be able to perform dry-run deployments to inspect what changes would take place in the environment or to detect errors before actually deploying any infrastructure changes.
You could complement these commands with your own custom analysis code to check for anything you care to verify, such as ensuring certain ports are not open to the public internet. Fortunately, there are usually open source static analysis tools that already provide common checks. For example, cfn_nag can be used to check for security issues in AWS CloudFormation templates, the native IaC framework for AWS. Other examples of cfn_nag checks include:
- Ensuring IAM policies are not overly permissive
- Ensuring encryption is enabled on services that provide it
- Ensuring security groups are not overly permissive
If an open-source IaC static analysis tool doesn’t offer a check that you want, it may be easier to add it to the existing code base than starting from scratch.
You can experience first-hand how to instrument IaC static analysis within a CI/CD pipeline in Cloud Academy’s Hands-on Lab: Static Analysis and Alerting for Infrastructure as Code. The lab uses Terraform as the IaC framework and Jenkins for its continuous integration pipeline. You will learn about the built-in static analysis capabilities in Terraform as well as two open-source static analysis tools that improve on Terraform’s native capabilities. New infrastructure code is continuously integrated by pushing to a Git repository. You will also learn how to configure Amazon SNS notifications based on the results of the static analysis. This is the final environment for the lab:
Complementing Static Analysis
While static analysis tools are continuously improving, they are not a panacea for all of your code quality and security needs. Instead, think of them as one part of a more comprehensive solution for improving the quality and security of your application and infrastructure code. Occasionally you will still need to employ traditional application unit and integration tests, or even tests for your infrastructure frameworks. You’ll be able to test the Serverspec infrastructure testing framework for yourself in our Hands-on Lab, Infrastructure Testing with Serverspec.
Security is another important category of automated testing frameworks. Learn how to Protect Your Code Against Attacks with Gauntlt in this Hands-on Lab. With Gauntlt, you can write automated tests for several popular security analysis tools, and it can easily be extended to others.
Ensuring secure applications is an important aspect of security. Transport Layer Security (TLS)/Secure Sockets Layer (SSL) protocols is the standard for securing communications on the web. Learn about Best Practices for Deploying SSL/TLS and tools for testing SSL/TLS deployments in this Cloud Academy lab.