Securing your CI/CD Pipelines

Introduction

This project was developed by Joshua-jebaraj

Motivation

The Main Motivation of this project is to learn how to implement the Security using CI/CD

For Deploying the application I took Simple Python-application developed by we45

The complete code for the deployment can be found at My-GithubRepo

The Guide can be found here

The Project covers the below Topics

⚠ Note This project was developed only for learning purpose

SAST

  • SAST stands for Static Application Security Testing
  • It is the methodology for finding the security flaws in the application from the source code
  • It is White-box Security testing methodology

In SAST phase we are going to perform below scan

ToolsUses
SCAScan for security flaws in dependency
Secret ScanningScan for sensitive information in the codebase
SASTScan for security flaws in the application code

SCA

SCA stands for the Source Composition Analysis here we are scanning the dependency (eg library) used in the application for security vulnerabilities

Since the application is based on the python I am going to use Pyraider tool which helps

Github actions

Below is the Github action for performing the SCA

name: sca on: push: jobs: checkout-repo: runs-on: ubuntu-latest steps: - name: Checkout 🛎️ uses: actions/checkout@v2 - name : Installing the sca run : | pip install pyraider cd app pyraider check -f requirements.txt

References

  1. https://pypi.org/project/pyraider/

Secret-Scanning

Developers often tends to embed the sensitive information like apikeys,passwords and push it to the code-base When the attacker able to get access to the sensitive information they can use these credentials and abuse the application

To prevent the secret pushed into the code base we are going to use the tool called truffleHog which scans the repository for sensitive information like passwords,API keys

Note The above technique I am using is only to able to scan for the secrets in the source-control after it is pushed Ideally you should have precommit hooks inorder to prevent the code being commit

TruffleHog is the python based tool used to scan the repositories the sensitive information

Github Action

name: secret-scanning on: push: jobs: checkout-repo: runs-on: ubuntu-latest steps: - name: Checkout 🛎️ uses: actions/checkout@v2 - name : Installing secret-scanning tool run : | pip3 install truffleHog truffleHog --regex --entropy=False .

References

  1. https://github.com/trufflesecurity/truffleHog

SAST SCAN

In this SAST phase we are going to scan through the application source code for security flaws

Since the application is based on Python I am going to use the tool called bandit

Github actions

name: sast on: push: jobs: checkout-repo: runs-on: ubuntu-latest steps: - name: Checkout 🛎️ uses: actions/checkout@v2 - name : Installing the bandit tool run : | pip install bandit bandit -r app

References

  1. https://pypi.org/project/bandit/

DAST

  • DAST stands for Dynamic application security testing
  • It is the methodology for finding the security flaws in the application when running
  • It is Black-box Security testing methodology

For performing the DAST I am going to use the ZAP to scan the web-application for security flaws. To provision the Infra I am going to use the Terraform and spin up the simple server and deploy the application and run the zap against the application deployed on the server and tear down the Infrastructure after the scanning is done

DAST

Pre-requisite

Before Implementing the Github Actions there are couple of steps need to be done

  1. Go to the Digital-Ocean and create the Personal token with write access

Copy the value of the Token Store it in the GITHUB_SECRETS

secret

Github Actions

name: Dast on: push: jobs: checkout-repo: runs-on: ubuntu-latest steps: - name : Install terraform run : | sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" sudo apt-get update && sudo apt-get install terraform terraform version - name: Checkout 🛎️ uses: actions/checkout@v2 - name: Provision the Infra run : | cd infra sed -i 's/secret/${{ secrets.DO_API}}/g' terraform.tfvars cat terraform.tfvars ssh-keygen -m PEM -f pentest_key -N "" ls terraform init terraform plan terraform apply --auto-approve GITHUB_IP=$(terraform output --raw ip_address) GITHUB_URL=http://$GITHUB_IP:5050/ echo "url=$GITHUB_URL" >> $GITHUB_ENV - name: ZAP Scan uses: zaproxy/action-full-scan@v0.2.0 with: target: "${{ env.url }}" - name: Destory if: ${{ always() }} run : | terraform destroy --auto-approve

The result can be found under the Result section

image

References

  1. https://github.com/marketplace/actions/owasp-zap-full-scan
  2. https://github.com/salecharohit/do-pentest

Container Security

Now days most applications are deployed in a containerized manner We have to make sure the container that used for deploying the application is also secure

To Secure the Docker container I am going to use the below two tools

ToolsUses
hadolintScans the Dockerfile and suggest the best practices for building the Docker container from the Dockerfile securely
docker scanScan for security flaws in the Docker Image that created from the Dockerfile

Github Actions

name: Container Scan on: push: jobs: checkout-repo: runs-on: ubuntu-latest steps: - name: Checkout 🛎️ uses: actions/checkout@v2 - name : Scanning for docker image run : | docker build -t test . docker scan test - name : Scanning for Dockerfile if: ${{ always() }} run : | docker run --rm -i hadolint/hadolint < Dockerfile

References

  1. https://github.com/hadolint/hadolint
  2. https://docs.docker.com/engine/scan/

Infrastructure security

Even though we use the containers for deployment we have to make sure the underlying infrastructure is also secure.To harden the underlying Infrastructure I am going to use Ansible. Ansible is configuration management tool that help to configure the servers via code. I am going to use Ansible-role to perform the set of task to harden the underlying Infrastructure

Github Actions

name: Infra-scan on: push: jobs: checkout-repo: runs-on: ubuntu-latest steps: - name: Checkout 🛎️ uses: actions/checkout@v2 - name : Installing ansible run : | sudo apt update sudo apt install ansible ansible-galaxy --version - name: Setting up the ansible run : | cd ansible echo "$SSH_KEY" > pentest_key chmod 600 pentest_key echo "$IP" >> inventory ansible-galaxy collection install devsec.hardening ansible-playbook playbook.yaml env: SSH_KEY: ${{secrets.KEY}} IP: ${{secrets.IP}}

Reference

  1. https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

  2. https://dev-sec.io/

SBOM

Software Bill of material is list of components(third party) present in the Code

To generate the SBOM I am going to use cyclonedx

I am going to use CycloneDX Python Module to generate the SBOM since the application is based on the python

Github Action

name: sbom on: push: jobs: checkout-repo: runs-on: ubuntu-latest steps: - name: Checkout 🛎️ uses: actions/checkout@v2 - name : Installing the cyclonedx-bom run : | pip install cyclonedx-bom cd app cyclonedx-py - uses: actions/upload-artifact@v1 with: name: report path: ${{ github.workspace }}/app/bom.xml name: 'Upload Package'

References

  1. https://www.synopsys.com/blogs/software-security/software-bill-of-materials-bom/
  2. https://github.com/CycloneDX/cyclonedx-python

Compliance as Code

Compliance as code as the name implies we are writing set of compliance-controls as the code To achieve compliance as code I have used Inspec tool Instead of writing the controls on my own I have used premade compliance check written by the community. I have used devsec linux profile to check my Infrastructure against the CIS compliance

Github Actions

name: Compliance as code on: push: jobs: checkout-repo: runs-on: ubuntu-latest steps: - name : Installing Inspec run : | curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P inspec inspec version - name: Setting up chef run : | echo "$SSH_KEY" > pentest_key chmod 600 pentest_key inspec exec https://github.com/dev-sec/linux-baseline --key-files <key-location> --target ssh://root@$IP --chef-license accept env: SSH_KEY: ${{secrets.KEY}} IP: ${{secrets.IP}}

Reference

  1. https://github.com/dev-sec/linux-baseline
  2. https://docs.chef.io/inspec/install/