CFripper — a static code analysis tool for CloudFormation scripts
Automating AWS infrastructure security
Skyscanner’s products are powered by hundred of services hosted on AWS. In order to be able to deploy changes and new services to production with zero clicks we have an automated pipeline that is responsible for building, testing and deploying new code, and provisioning and configuring new infrastructure. Our goal as the Product Security Squad is to inject security into the pipeline as early as possible, and make sure that the relevant security scans and audits are performed at every step, minimizing the risk of any vulnerable code getting into production.
In this blogpost we will focus on one of these steps that is responsible for deploying our infrastructure, more specifically CloudFormation and CloudFormation scripts. We will talk about why it is important to treat CloudFormation scripts as part of the code and perform security scans on them. We will have a look at the tools the we built for that, CFripper, and talk about how it works, what it looks for and how you can use it as well.
Infrastructure as Code (IaC)
CloudFormation scripts are used by Amazon AWS to automate the provisiong of infrastructure in the cloud. They are just simple JSON or YAML files that describes the infrastructure components that need to be deployed, how they communicate, their permissions and more. To quote Amazon themselves: “It’s just code. You can author it with any code editor, check it into a version control system, and review the files with team members before deploying into production”. And as with any code, mistakes and bugs are bound to appear, which may have impact on the security of the stack or even the cluster, and it is our responsibility as the Product Security Squad to make sure that these misconfigurations are detected as early as possible in the pipeline.
CFripper is a Python tool that we wrote at Skyscanner that aims to prevent those vulnerabilities from getting to our production infrasturcture. As with the other security tools that we use, CFripper is part of our CI/CD piepeline. It runs just before a CloudFormation stack is deployed or updated and if the CloudFormation script fails to pass the security check it fails the deployment and notifies the team that owns the stack.
How does it work?
One of the first things CFripper needs to do is transform the CloudFormation script into a format that is easy to handle and manipulate. This is a three step process: the script is downloaded from S3, then it is converted from JSON/YAML to a Python dictionary and finally it is parsed by pycfmodel to be converted into a Python object. pycfmodel helps us to eliminate code repetition and common bugs by providing a Python model of the CF script that has various helper functions that help us with frequently performed operations.
Once CFripper has the model, it runs it through all the rules, checking for failures. The rules are short Python files that operate on a CloudFormation resource (AWS::EC2::Volume, AWS::IAM::Role, etc.), performing various validations and checks. For example, there are rules that check for open S3 buckets, unnecessarily wide port ranges on EC2 instances, disabled encryption on databases and more.
Let’s take a look at the S3BucketPolicyWildcardActionRule. This is a rule that looks for S3 bucket policies that allow potentially harmful actions to be performed on S3 buckets. Since pycfmodel parses the CloudFormation script and conveniently puts that same resources into a list, we can iterate over the list of AWS::S3::BucketPolicy resources and check each one of them for that configuration. pycfmodel also provides a helper function on policy documents that returns all the wildcard allowed actions. We can then add a failure for every match that we get and report that at the end of the execution.
Rules also support monitor mode. In this mode, failures of the rule will not trigger a failure of the execution, but instead will only be logged and reported. This is good for testing new rules on large traffic and collecting data, without blocking any deployments. When the rule is ready to be enabled it is just a matter of flipping the flag.
At the end of the run, after CFripper has gone through all the rules and applied them to the relevant resources it returns a summary of the results detailing the failing rules and the resources that triggered the failures. The report also includes failed monitor mode rules as well as warnings.
The current open source version of CFripper contains of set of built-in rules ranging from to. We will continue to add any new rules that we develop in-house but we will also appreciate any rules that you might have developed while using CFripper. Please read the contribution guide and submit a pull request.
SEE the world with us
Many of our employees have had the opportunity to take advantage of our Skyscanner Employee Experience (SEE) — a self-funded, self-organized programme to work up to 30 days during a 24 month period, in some of our 10 global offices. There is also the opportunity to work for 15 days per year from their home country, if an employee is based in an office outside of the country they call home.
Like the sound of this? Look at our current Skyscanner Product Engineering job roles.
About the authors
Our names are Valentin Tunev and Xavier Mendez, Security Engineers working in the Product Security Squad in Barcelona and Sofia. We look at the security of our platform, Software Development Lifecycle, Security Engineering, Automation and protecting our users. Kudos to Patrick Menlove and Iain Jess who started working on this idea.