Enabling and Configuring Security Scans and Policies #
In this section, we will go over the security scans which GitLab offers. We will then setup all of the scans and run them on our main branch.
What Security Scans does GitLab offer #
GitLab offers a variety of security scans to enhance application security. Some scanners will scan the static source code, and others will scan the running application for vulnerabilities.
The scanners use both OpenSource and GitLab built tools, which vary by language. The language in the application is auto-detected by GitLab. For these OpenSource tools, the infrastructure is maintained by GitLab, saving users lot’s of cost and hassle maintaining.
We will go over the following scanners:
- Static Application Security Testing (SAST): analyzes your source code for known vulnerabilities.
- Dynamic Application Security Testing (DAST): analyzes your running application for known vulnerabilities.
- Container Scanning: scans Docker images for known vulnerabilities
- Dependency Scanning: scans project dependencies for known vulnerabilities
- License Scanning: scans licenses to see if they are incompatible with a set policy
- Secret Detection: Scans for secrets checked into source code
- Infrastructure as Code Scanning: Scans your IaC configuration files for known vulnerabilities. IaC scanning supports configuration files for Terraform, Ansible, AWS CloudFormation, and Kubernetes.
- Coverage-Guided Fuzzing: Sends random inputs to an instrumented version of your application in an effort to cause unexpected behavior.
- Web-API Fuzzing: Sets operation parameters to unexpected values in an effort to cause unexpected behavior and errors in the API backend
- DAST API-Scanning: analyzes the APIs of your running application for known vulnerabilities using REST, SOAP, GraphQL, Form bodies, JSON, or XML definitions.
- Code Quality Scanning: ensures your project’s code stays simple, readable, and easy to contribute to.
- Operational Container Scanning: scans the container images in your cluster for known vulnerabilities.
Step 1: Adding Security Scans to the pipeline #
Security scanners can be added in 2 different ways. Either by using the Security Configuration UI or by simply editing the .gitlab-ci.yml.
Since security scanners have already been added to this project via templates, you can see how they are defined and configured and by viewing the .gitlab-ci.yml.
Below I’ll explain how the security scanners work and separate them into 3 different categories:
- Static Security Scanners
- Dynamic Security Scanners
- Application and Web-API Fuzzers
Static Security Scanners #
Static security scanners examine the static source code in your project and perform pattern matching on syntax, versions, etc. in order find known vulnerabilities. They obtain the vulnerabilities from a CVE database and parse data in order to provide you with the following:
- Project (may include line of code)
- Scanner type
- Relevant links (Education/Training, Solutions)
- Identifiers (CVE, CWE)
Dynamic Security Scanners #
Dynamic scanners examine the running application, and send requests in order to find vulnerabilities within the system. Dynamic scanners are not aware of the underlying code, and perform request on a block-box.
Note: Since requests are sent to the application and responses are received, they are included along with the same data as static scanners (listed above). You can download Postman specs in order to replicate the requests, which is useful for manual testing.
Application and Web-API Fuzzers #
Fuzzing or Fuzz-Testing is the process of sending random or malformed data to an application or instrumented function in order to cause unexpected behavior. This helps you discover bugs and potential security issues that other QA processes may miss.
GitLab includes Web-API Fuzzing (fuzz testing of API operation parameters) and Coverage-Guided Fuzzing (sends random inputs to an instrumented version of your application).
Step 2: Explanation of each of the CI/CD job #
There’s a bunch of CI/CD jobs that do a bunch of different things, I’ll briefly explain them below:
- build: Builds the container image for using the application in Kubernetes
- pages: Build the documentation using Go Hugo Static Site Generator
- unit: Runs Unit Tests from the application
- gemnasium-python-dependency_scanning: Overwrites the pre_script of dependency scanning to install required system dependencies
- container_scanning: Overwrites the image being scanned depending on the branch
- license_scanning: Overwrites the pre_script of license scanning to install required system dependencies
- secret_detection: Overwrites the variable to allow historic secret detection
- coverage-guided-fuzzing: Runs fuzzing on a provided instrumented file
- deploy: Installs ingress, mariadb, and notes application to Kubernetes cluster.
- dast: Overwrites paths used for running dast
- dast_api: Overwrites paths used for running dast_api
- apifuzzer_fuzz: Overwrites paths used for running api-fuzzing
- cleanup-db: Resets notes which have been added via dynamic security scans
Step 3: Setting up Merge-Request Approvals (Vulnerabilities) #
Code review is an essential practice of every successful project. Approving a merge request is an important part of the review process, as it clearly communicates the ability to merge the change.
GitLab provides Security guard-rails to prevent vulnerable code from being merged without approval. This includes vulnerabilities as well as incompatible licenses. Now let’s setup these guardrails, known as merge-request approvals.
Go to the the Security & Compliance left navigation menu and press Policies
Click on the New policy button
Press the Select policy button under the Scan result policy section
Fill out the following information:
- Name: Policy Name
- Description: Policy Description
Check the Enabled button under Policy status
Create a Rule
Select allfind(s) more than
Newly detectedvulnerabilities in an open merge request targeting
- Create an Action
THEN Require approval from
1of the following approvers
Add any username/group (other than yours) in the Search users or groups drop down
Click on the Configure with a merge request button
Merge the newly added code
Note: You will notice a new project was created to store the policies
Step 4: Creating a License Policy #
License Policies allow you to declare licenses as either approved or denied. When Merge-Request Approvals are set up a denied license will block an MR from being merged.
Under the Security & Compliance left navigation menu, go to License Compliance
Click on Policies
Click on Add license and related policy
Type in Apache License 2.0, select Deny, and press Submit
The Apache License 2.0 should now be added with a confirmation
Follow Steps 3-5 for GNU Affero General Public License v3 or later (AGPLv3+)
Note: Make sure you type it completely as is, and don’t select from the dropdown, License Scanning currently requires exact patterns.
Step 5: Setting up Merge-Request Approvals (Licenses) #
Setting up the License Check enables us to require approval if any licenses within the denylist are present. We setup the denylist in the previous step.
Click on the Update approvals button
Set Approvals required to
Add any username/group other than yours in the Search users or groups drop down
Click on the Update approvers button
Note: You should now have a confirmation that License Approvals have been enabled
Congratulations! You have now successfully run Security Scans and enabled DevSecOps for your application.