# GitLab Security Essentials V2 Notes:
- Introduce yourself as the instructor - Add instructor's name and (optionally) email to chat, since they aren't on the title page - Hi, I'm Barry Johnson and I'm with Seek Quality and today we are here to talk about security in gitlab.
---
# Class details
- 2 x 4-hour sessions - Lecture, demos, hands-on labs, optional exam - Basic but real demos and labs - You'll get a copy of all materials - Assumes basic knowledge of GitLab and Git - **
All demos and labs are on GitLab 14.9 or above
**
Notes: - I'll ask a little later on about people's experience level with GitLab and Git. ---
# Learning objectives
##
Extension of the CI/CD class
- What the **Secure stage** covers in the SDLC - What **problems** each scanner looks for - **Enabling** and **configuring** each scanner - Reading different scanner **reports** - Managing **vulnerability remediation**
Notes: - For now just know that this is a very high level overview of Gitlab Security. - Too many configuration options to go into all of them. Default options often work fine. Docs give more details. - Like learning a foreign language: you are taught the basic framework, and you can learn extra details on your own. ---
# Agenda
### Part 1 - Introducing the Secure stage - SAST, secret detection, DAST
**Break** ☕
- Dependency scanning
### Part 2 - Container scanning
- License compliance
**Break** 🍩
- Fuzz testing
- Infrastructure-as-Code testing
Notes: - Call for a 5-min break whenever you want - It's **always** a good time for questions or comments - but, if it's something that's going to take a while, I'll make a note and get back with you later on. ---
# Your background
**GitLab experience?** beginner, intermediate, advanced
**GitLab CI/CD experience?** beginner, intermediate, advanced
**Git experience?** beginner, intermediate, advanced
**Have you taken the CI/CD class?**
Notes: n/a ---
# Getting the most out of training
**Please interrupt with questions or comments** - Use microphone or chat - Video optional - We can slow down or repeat info for non-native English speakers
**Please interrupt with questions or comments** - Use microphone or chat - Video optional - We can slow down or repeat for non-native English speakers
**OK to forget most of the details** - Show you what's possible - Give you confidence to re-learn as needed
**Expect circular explanations and repetition**
Notes: n/a --- ## Hands-on Lab Guide `https://about.gitlab.com/handbook/customer-success/professional-services-engineering/education-services/secessentialshandson.html`
## Create your training environment group 1. If you've taken an earlier GitLab class, visit
`https://ilt.gitlabtraining.cloud` and **
log out
** 1. Visit `https://www.gitlabdemo.com/invite` 1. Enter the invitation code (see chat) for this class
to get new credentials Notes: -
Paste Lab Guide URL into chat:
https://about.gitlab.com/handbook/customer-success/professional-services-engineering/education-services/secessentialshandson.html
- Do labs in training sandbox: private group within GitLab -
Paste into chat:
https://www.gitlabdemo.com/invite
-
Paste invitation code in chat
- Do certification in the same environment - Environment expires after 7 days. - We can give you more time, **but only if you let us know before it expires**. Email us. - **Before going on:** questions about what we’ll cover, or course mechanics? --- # Module 1:
Introduction to the Secure stage
**At the end of this module, you will understand:**
- How GitLab divides the SDLC into stages - How security scanning fits into GitLab flow - The types of scanners GitLab provides - GitLab’s vulnerability management feature Notes: n/a ---
# GitLab’s 10 SDLC stages
Notes: - Explain how SDLC is divided into 10 stages - Google "GitLab maturity" and show live version of this page - Basics course focused on **Create** stage **This is Bold** - CI/CD course focused on **Verify** and **Package** stages - This course focuses on **Secure** stage --- # Secure stage and DevOps
Notes: - Alternative view of the DevOps lifecycle you might not have seen before - Unlike some other companies, GitLab uses "DevOps" synonymously with "SDLC" - Left side = dev stages, right side = ops stages - Securing is relevant to both dev and ops stages: find vulnerabilities early so they aren't exploited in production --- # 8 security scanners
- Static Application Security Testing (SAST) - Secret detection - Dynamic Application Security Testing (DAST) - Dependency scanning - Container scanning - License compliance - Fuzz testing - Infrastructure-as-Code scanning Notes: - 8 scanners and 2 features (but always under development) - These are the scanners - Class covers scanners in this order - All scanners but SAST, Secret detection, and Container scanning (for 15.0) are ultimate only - "Security" has different meanings at GitLab - Most scanners focus on traditional security vulns - Some focus on bugs - Consider bugs part of security, because they can be exploited by black hat types (e.g., DOS) - 1 focuses on legal compliance - **SAST** looks for known problems in source code (e.g., unvalidated user input leads to command injection) - **Secret detection** looks for hard-coded secrets in source code (e.g., passwords) - **DAST** passively or actively calls a web app or an API to look for security vulnerabilities - **Dependency scanning** looks at project’s dependencies to see if there are known vulnerabilities with those versions (e.g., third-party YAML-parsing library) - **Container scanning** looks for known vulnerabilities in Docker images your app’s Docker image is built on top of - **License compliance** makes sure dependencies use licenses that are compatible with your project - **Fuzz testing** sends random input to your functions, trying to cause unexpected problems (e.g., 200-character password or Klingon characters in Unicode) - **Infrastructure-as-Code testing** scans IaC configuration files (e.g., Ansible, Terraform) for known security vulnerabilities --- # Supporting features
- Security reports - Vulnerability management Notes: - These are "supporting features" that let you use the scanners more easily and make the more powerful. - **Security reports** show security vulnerabilities in different places and different ways - **Vulnerability management** lets you view problems in several places within GL and accept/dismiss/mark for action --- # Security scanning workflow
Notes: 1. A commit to a feature branch triggers apipeline, which runs security scanners (either against source code or running code in a review app) 1. Vulnerabilities are displayed in several places. The Developer either dismisses or accepts them. Fixes immediately or creates an issue with 1 click 1. We Merge the feature branch into the default branch & eventually deploy to production 1. THe Security team tracks any remaining vulnerabilities that the developer didn’t fix. Either dismisses them or make a new issue to fix them in the future.
Workflow depends on viewing the results of the security scans. Where do you do that?
--- # Report locations and types
| # |
Where?
| What does it show? | |-----|-----|-----| | 1 | Vulnerability report | Vulnerabilities on **default** branch | | 2 | Pipeline details | Vulnerabilities on **pipeline's** branch | | 3 | Merge request | Vulnerabilities on **pipeline's** branch but **not** on **default** branch, or vice versa (delta or diff) | Notes: - This is just a **preview.** Will see all 3 of these in action later - Super important to understand differences between what is shown in the 3 reports, since they are subtly different - Will refer to these 3 report locations repeatedly throughout this course --- # All reports show all results
Notes: - Each report location shows problems found by all the scanners - User can filter vulnerabilities by scanner - We'll see this filtering later on, when we look at the individual scanners and their results - IaC scanning isn't shown here because it's new, but its results also show up in the same reports as all the others --- # Scanners vary by language
- GitLab detects computer languages in your project - Scanners use different tools for different languages - OK to have multiple languages
| Language | SAST Tools | Trigger files | |-----|-----|-----| |
Python | Bandit
Semgrep | `*.py`
`requirements.txt` | |
Ruby | Brakeman | `*.rb`
`Gemfile` | Notes: - These are just 2 examples. Same principles hold for other languages - Most scanners support most major languages (Java, JavaScript, Python, Ruby, C, C#) --- # Common details for all scanners
- Packaged as **Docker images** - Require GitLab Runner with **Docker** or **Kubernetes** executor - Updated **monthly** (at least) - Most findings include **links** to outside vulnerability DBs - Finding vulnerabilities does **not** stop the pipeline - Enabled by **Auto DevOps** Notes: -
Grab bag slide of details that apply to all scanners
- Users can probably ignore executors: usually something the GitLab admin worries about - Open-source tools are updated frequently and those updates are available to GL users - Explain Auto DevOps - Auto DevOps is a good starting place, but not used by most GitLab customers --- # Integrating outside scanners
You can integrate **most** third-party
security scanners into GitLab CI/CD pipelines
* Triggered automatically within pipeline * Results appear in GitLab reports Notes: - GL-provided scanners might be all you need. Start with them and see before integrating others. ---
# Q&A: Intro to the Secure stage Notes: n/a --- # Module 2:
SAST, secret detection, DAST
**At the end of this module, you will be able to:**
- Explain what SAST, secret detection, and DAST do - Enable and configure all 3 scanners in a pipeline - View the reports from all 3 scanners - Track progress on dealing with vulnerabilities Notes: n/a --- # What is SAST?
-
**S**
tatic
**A**
pplication
**S**
ecurity
**T**
esting - Scans source code for security vulnerabilities - Does not run the code Notes: - Examples: - SQL injection - Divide by 0 - Plenty of competitors, but they aren’t integrated into a single app like GL - JetBrains IDEs have built-in - Fortify - Veracode --- # Steps for using SAST
1. Enable and configure SAST 1. Run pipeline 1. Review findings 1. Take action Notes: - SAST requires same 4 steps as for almost all GitLab security scanners - We'll see each in action in a live demo --- # Enable SAST ##
Manual
Edit `.gitlab-ci.yml` ```yaml stages: - test include: - template: Security/SAST.gitlab-ci.yml ```
##
GUI
1. **Security & Compliance > Configuration** 1. **Static Application Security Testing > Enable** 1. Merge auto-generated MR to edit `.gitlab-ci.yml` Notes: n/a --- # Configure SAST
##
Sample options
- Set severity thresholds - Disable individual scanners - Pin scanner versions
##
3 config methods
- GUI - Set global var in `.gitlab-ci.yml` - Override job definition, set
job-scoped var in `.gitlab-ci.yml`
Notes: - Different config options are set differently, so look up details in docs - All scanners use 1 or more of these methods - **Can't mix & match** config options and config methods! - Must look in docs to see which method to use for which options. ---
# SAST demo Notes:
Demo enabling and configuring SAST with the GUI
### Make demo project
- Make project `Security Demo` in session namespace - Disable Auto DevOps: - **Settings > CI/CD > Auto DevOps** - On `main`, make a bare-bones `.gitlab-ci.yml`: ```yaml stages: - test dummy-job: stage: test script: - echo "in dummy job" ``` - Commit `.gitlab-ci.yml`
### Enable and configure SAST using the GUI
- **Security and Compliance > Configuration** - **SAST > Enable** - **SAST Analyzers > Expand** - Disable 2 analyzers: - **Semgrep** (to speed up pipeline) - **Sobelow** (to show that you can disable multiple scanners)
### Generate an MR to edit `.gitlab-ci.yml`
- Click **Create Merge Request** - Click **Create merge request** (again) on MR creation page - Merge auto-created MR - View updated `.gitlab-ci.yml`
### Watch SAST run
- Show SAST not running in pipeline. Why? **Answer:** no source code to run against - Add `HelloWorld.py` to repo root dir: ```python print("Hello world") password = 'foo' ``` - Show pipeline running SAST - Show that job succeeded - **Don't look at any results yet!** Need to create the MR report first.
--- # Report locations and types
| # |
Where?
| What does it show? | |-----|-----|-----| | 1 | Vulnerability report | Vulnerabilities on **default** branch | | 2 | Pipeline details | Vulnerabilities on **pipeline's** branch | | 3 | Merge request | Vulnerabilities on **pipeline's** branch but
**not**
on **default** branch, or vice versa (delta or diff) | Notes:
- Want to show all 3 reports - First, need to make a branch and MR to see MR report
- In **Security Demo** project, make **branch-a** - On **branch-a**, add vulnerability to `HelloWorld.py`: ```yaml tmp_dir = '/tmp' ``` - Python prefers you use built-in functions to create and manage temp dirs; making one manually is considered a security problem - Make MR for **branch-a** - When pipeline finishes, demo all 3 results locations - Vulnerability report shows just password vulnerability, not `tmp/` vulnerability - Pipeline details page for **branch-a** pipeline shows 2 vulns - MR shows **diff**: 1 new `tmp/` vuln, which is only on **branch-a**
--- # Take action 4 possible statuses for each vulnerability
-
Needs Triage
-
Dismissed
-
Confirmed
-
Resolved
"Taking action" = changing a vulnerability’s status Identical process for
**most**
security scanners Notes:
Demo:
### Take action on a legit vuln
- **Pipeline details > Security tab** - Change password vuln to **confirm** status - Create issue for password vuln
### Fix vuln on a branch
- On **branch-a** change `'foo'` to `get_password()`
### See fixed vuln's status in MR
- Wait for pipeline to finish - Go to MR to see password vuln marked as **fixed**
### Merge the fix
- Merge MR - Wait for pipeline to finish - **Security & Compliance > Vulnerability Report**
### Mark fixed vuln as resolved
- Mark password vuln as **resolved**
### Dismiss an ignorable vuln
- Change status of `tmp/` vuln to **dismissed**
--- # What is secret detection?
- Looks for secrets inside files in project’s repo - US Social Security numbers - Private SSH keys - Deploy keys - etc. - **Historic** mode for unscanned repos - Used to be part of SAST, now separate - Uses open-source tool **Gitleaks**
Notes: - Might see references to Secret Detection that make it sound like it’s part of SAST, since it used to be. - Historic mode is important! -
Can anyone guess why?
- Answer: once you've added a secret, it’s always available in Git even after you delete it in a later commit. --- # Steps for using secret detection
1. Enable and configure secret detection 1. Run pipeline 1. Review findings 1. Take action Notes: - Same 4 steps as we saw for SAST - As with SAST, we'll see each step in a demo --- # Enable secret detection ##
Manual
Edit `.gitlab-ci.yml` ```yaml stages: - test include: - template: Security/Secret-Detection.gitlab-ci.yml ```
##
GUI
1. **Security & Compliance > Configuration** 1. **Secret Detection > Configure via Merge Request** 1. Merge auto-generated MR to edit `.gitlab-ci.yml` Notes: - 99% same as for SAST. - template name is different - GUI button says **Configure via Merge Request** instead of **Enable**, but does exactly the same thing --- # Configure secret detection
##
Sample options
- Enable historic mode - Which commits to scan - Which paths to exclude
 
##
Edit `.gitlab-ci.yml` - Set global variable - Override job definition and set job-scoped variable
Notes: n/a ---
# Secret detection demo Notes:
Demo enabling and configuring secret detection with the GUI
### Enable secret detection with GUI
- Go to **Security Demo** project - **Security & Compliance > Configuration > Secret Detection > Configure via Merge Request** - Accept the MR details - When pipeline finishes, merge the auto-created MR - Review the 1-line change to `.gitlab-ci.yml`
### Enable historic mode
- On **main**, open **Web IDE** - In `.gitlab-ci.yml`, configure secret detection to turn on historic scanning: ```yaml secret_detection: variables: SECRET_DETECTION_HISTORIC_SCAN: "true" ```
### Add two secrets to main
- Add a secret to `HelloWorld.py`: ```python database_connection_string = "postgres://secret_username:super_secret_password_mtst109238@dev-postgres:1111/dev-db" ``` - Add a private key file to root dir: `id_rsa` ``` -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,86C3F4011519BFBB PxyzMAlAmEu/Qkx9nPh696SU7/MjXpCpOnfF== -----END RSA PRIVATE KEY----- ``` - Commit to **main**
### See the results
- Watch pipeline run - Go to **Vulnerability Report** to show 2 detected secrets
--- # What is DAST?
-
**D**
ynamic
**A**
pplication
**S**
ecurity
**T**
esting - Scans a **running** web app for security vulnerabilities - SAST = white box, DAST = black box - URL vs. API - URL: start at home page, then spider the site - Passive vs. Active - Passive: send normal requests, analyze responses - Active: send malicious query strings, POST data, etc. - Uses open-source tool **OWASP Zed Attack Proxy** Notes: - Example of vuln found during passive scan: unexpected or misconfigured response headers - OWASP: Open Web Application Security Project. Well-regarded organization, highly respected tool. --- # Steps for using DAST
1. Enable and configure SAST 1. Run pipeline 1. Review findings 1. Take action Notes: - Same 4 steps you saw for SAST and secret detection --- # Enable DAST ##
Manual
Edit `.gitlab-ci.yml` ```yaml stages: - dast include: - template: DAST.gitlab-ci.yml ```
##
GUI
1. **Security & Compliance > Configuration** 1. **DAST > Enable** 1. Generate CI/CD configuration code fragment 1. Add fragment to `.gitlab-ci.yml` Notes: - Different stage compared to other scanners! -
**Can anyone guess why?**
- Answer: because you have to build and deploy code in an earlier stage before you can run DAST against it. - Template looks a little different: not in `Security/` dir --- # Configure DAST
##
Sample options
- Passive and/or active - URL and/or API - Target URL - Authentication creds
##
Config methods
- GUI - Set global var in `.gitlab-ci.yml` - Override job definition, set
job-scoped var in `.gitlab-ci.yml`
```yaml variables: DAST_WEBSITE: https://www.example.com ``` Notes: - DAST configuration is more complicated than most other scanners - Most DAST config possible via GUI ---
# DAST demo Notes:
Demo enabling and configuring DAST with the GUI
### Enable and configure DAST
- Return to project **Security Demo** - **Security & Compliance > Configuration > DAST > Enable** - Create new scanner profile: - `Scanner profile for class` - Leave all at defaults - Highlight **Passive scan mode** - Create new site profile: - `Site profile for class` - `https://www.example.com` or your favorite bank - Click **Generate code snippet**
### Edit .gitlab-ci.yml
- Click **Copy code and open .gitlab-yml file** - Paste snippet into **.gitlab-ci.yml** - Edit `.gitlab-ci.yml` for neatness - Commit `.gitlab-ci.yml`
### View the results
- Wait for pipeline to finish - See **Vulnerability Report** for DAST results - Filter to show only DAST results
--- # Q&A
**SAST**
**secret detection**
**DAST**
Notes: n/a --- # Lab 1 ##
SAST, secret detection, and DAST
- Enable, configure, and run SAST and
secret detection on a Python project - Enable, configure, and run DAST on
an external website - View and triage found vulnerabilities - Track and fix one vulnerability using
a branch and merge request
Notes:
- Paste lab 1 guide: https://about.gitlab.com/handbook/customer-success/professional-services-engineering/education-services/secessentialshandson1.html - Set timer for 20, check in then, expect 30 mins for most people
--- # Module 3:
Dependency scanning
**At the end of this module, you will be able to:**
- Explain what dependency scanning is - Enable and configure dependency scanning
in a GitLab pipeline - View the different dependency scanning reports Notes: n/a --- # What is
dependency scanning?
- Finds
**known**
security vulnerabilities
in project dependencies - Scans recursively: looks at
dependencies’ dependencies - Uses open-source tool **Gemnasium**
Notes: - Word “known” is important! Only finds problems that have already been discovered and catalogued somewhere by security experts. --- # Determining dependencies
Scanner uses
**package managers**
to discover project dependencies Notes: - Scanner looks for files that list dependencies. Varies by language.
- Google `gitlab dependency scanning` to see list of languages and package managers - Focus on **Supported Files** column for **Maven**, **Python**, **Ruby**
--- # Steps for using
dependency scanning
1. Enable and configure dependency scanning 1. Run pipeline 1. Review findings 1. Take action Notes: - Should look familiar: same 4 steps you saw for SAST, secret detection, and DAST --- # Enable dependency scanning ##
Manual
Edit `.gitlab-ci.yml` ```yaml stages: - test include: - template: Security/Dependency-Scanning.gitlab-ci.yml ```
##
GUI
1. **Security & Compliance > Configuration** 1. **Dependency scanning > Configure via Merge Request** 1. Merge auto-generated MR to edit `.gitlab-ci.yml` Notes: n/a --- # Configure
dependency scanning
##
Sample options
- Excluded analyzers - Automatic remediation - Which DBs to use
##
Config methods
- GUI - Set global var in `.gitlab-ci.yml` - Override job definition, set job-
scoped var in `.gitlab-ci.yml`
```yaml gemnasium-dependency_scanning: variables: DS_REMEDIATE: "false" ``` Notes: - Identical to configuring SAST & secret detection ---
# Dependency scanning demo Notes:
Demo dependency scanning by manually editing CI/CD config file
### Enable and configure dependency scanning - Return to project **Security Demo** - In **Web IDE** add template to `.gitlab-ci.yml`:
```yaml include: - template: Security/Dependency-Scanning.gitlab-ci.yml ```
- Add dependency to **old** version of Ruby on Rails (old means that it should have security problems) by adding `Gemfile.lock` in project root:
```gemfile GEM remote: https://rubygems.org/ specs: actioncable (6.0.0) actionpack (= 6.0.0) nio4r (~> 2.0) websocket-driver (>= 0.6.1) actionmailbox (6.0.0) actionpack (= 6.0.0) activejob (= 6.0.0) activerecord (= 6.0.0) activestorage (= 6.0.0) activesupport (= 6.0.0) mail (>= 2.7.1) actionmailer (6.0.0) actionpack (= 6.0.0) actionview (= 6.0.0) activejob (= 6.0.0) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) actionpack (6.0.0) actionview (= 6.0.0) activesupport (= 6.0.0) rack (~> 2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) actiontext (6.0.0) actionpack (= 6.0.0) activerecord (= 6.0.0) activestorage (= 6.0.0) activesupport (= 6.0.0) nokogiri (>= 1.8.5) actionview (6.0.0) activesupport (= 6.0.0) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) activejob (6.0.0) activesupport (= 6.0.0) globalid (>= 0.3.6) activemodel (6.0.0) activesupport (= 6.0.0) activerecord (6.0.0) activemodel (= 6.0.0) activesupport (= 6.0.0) activestorage (6.0.0) actionpack (= 6.0.0) activejob (= 6.0.0) activerecord (= 6.0.0) marcel (~> 0.3.1) activesupport (6.0.0) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) zeitwerk (~> 2.1, >= 2.1.8) builder (3.2.4) concurrent-ruby (1.1.9) crass (1.0.6) erubi (1.10.0) globalid (0.5.2) activesupport (>= 5.0) i18n (1.8.10) concurrent-ruby (~> 1.0) loofah (2.12.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) marcel (0.3.3) mimemagic (~> 0.3.2) method_source (1.0.0) mimemagic (0.3.10) nokogiri (~> 1) rake mini_mime (1.1.2) minitest (5.14.4) nio4r (2.5.8) nokogiri (1.12.5-x86_64-darwin) racc (~> 1.4) racc (1.6.0) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) rails (6.0.0) actioncable (= 6.0.0) actionmailbox (= 6.0.0) actionmailer (= 6.0.0) actionpack (= 6.0.0) actiontext (= 6.0.0) actionview (= 6.0.0) activejob (= 6.0.0) activemodel (= 6.0.0) activerecord (= 6.0.0) activestorage (= 6.0.0) activesupport (= 6.0.0) bundler (>= 1.3.0) railties (= 6.0.0) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.4.2) loofah (~> 2.3) railties (6.0.0) actionpack (= 6.0.0) activesupport (= 6.0.0) method_source rake (>= 0.8.7) thor (>= 0.20.3, < 2.0) rake (13.0.6) sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) thor (1.1.0) thread_safe (0.3.6) tzinfo (1.2.9) thread_safe (~> 0.1) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) zeitwerk (2.5.1) PLATFORMS x86_64-darwin-19 DEPENDENCIES rails (= 6.0) BUNDLED WITH 2.2.11 ```
### Configure dependency scanning - Exclude 1 of the 2 Ruby dependency scanners by setting global variable
```yaml variables: DS_EXCLUDED_ANALYZERS: bundler-audit ```
- Disable auto-remediation by overriding job defn and setting a job-scoped variable:
```yaml gemnasium-dependency_scanning: variables: DS_REMEDIATE: "false" ```
### Run and view findings
- Run pipeline. Notice just **gemnasium** job is running, but **bundler-audit** job is not - Show Vulnerability Report - See Dependency Scanning findings in Vulnerability Report
--- # Q&A
##
Dependency scanning
Notes: n/a --- # Lab 2 ##
Dependency scanning
- Enable and run dependency scanning
on a Python project - View, triage, and take action on
found vulnerabilities
Notes:
- Paste lab 2 guide: https://about.gitlab.com/handbook/customer-success/professional-services-engineering/education-services/secessentialshandson2.html
- Lab 2 has optional but recommended instructions for commenting out earlier scanners, to speed up your lab pipeline - Skills practiced here are very similar or identical to how you use the other scanners, so worth going through slowly and carefully. - **Warning:** this lab runs Dependency Scanning twice, and it can take 3 or 4 minutes per run. - Set timer for 10, check in then, expect 15 mins for most people ---
# Welcome back! ---
# Agenda
### Part 1 - Introducing the Secure stage - SAST, secret detection, DAST
**Break** ☕
- Dependency scanning
### Part 2 - Container scanning
- License compliance
**Break** 🍩
- Fuzz testing
- Infrastructure-as-Code testing
Notes: - Call for a 5-min break whenever you want - It's **always** a good time for questions or comments --- # Part 1 review [//]: # (shrink text to make it all fit on one screen)
1.
**true/false:** GitLab security scans only happen after development is completely finished.
1.
**true/false:** You do not need to deploy your code in order to scan it with SAST.
1.
**true/false:** If Secret Detection’s historic mode finds a hard-coded password in a commit from last year, you should make a new commit that removes the password from your source code.
1.
**true/false:** DAST looks for vulnerabilities by calling your app’s URLs and/or APIs.
1.
**true/false:** Dependency Scanning looks at your project’s dependencies and their dependencies, and so on.
1.
**true/false:** If a security scanner finds any vulnerabilities, it halts the pipeline.
1.
Which report type shows a delta between the vulnerabilities on the default branch and vulnerabilities on a feature branch? (**vulnerability report, pipeline details,** or **merge request**)
1.
**true/false:** All scanner types support the same computer languages.
Notes: n/a --- # Module 4:
Container scanning
**At the end of this module, you will be able to:**
- Explain what container scanning is - Use container scanning in a GitLab pipeline - View the different container scanning reports Notes: n/a --- # What is container scanning?
- Finds **
known**
vulnerabilities in
packages in Docker images - **OS** packages - **Language** packages (optional) - **Default** or **Dockerfile**-installed packages - Uses open-source tools **Trivy** and **Grype** - Most useful when deploying Dockerized app - Scans images in project's container registry
**alpine:3.14.1** had 4 problems as of February 2022 - 2 CVE vulnerabilities in **libcrypto1.1** - 2 CVE vulnerabilities in **libssl1.1**
Notes: - As with dependency scanning, the word **known** is important. It does **not** do SAST-style scanning on Docker images to find new problems. - Trivy is default. Grype supports slightly different Linux distros. Some distros work with both. Experiment to see which works best. -
Show list of supported OS images: `https://docs.gitlab.com/ee/user/application_security/container_scanning/#supported-distributions`
- Trivy and Grype scan packages installed by the OS's package manager: OpenSSL RPM or DEB or by the Dockerfile - Trivy scans packages installed by a language: Ruby on Rails gem - Language scan results might duplicate Dependency Scanning results - Can scan Docker images in other locations, but default is to look in project's container registry - Example: even going back a single patch release (as of February 2022) for Alpine reveals 4 vulnerabilities! Later we'll see how many are detected today, now that more time has passed. --- # Steps for using
container scanning
1. Enable and configure container scanning 1. Run pipeline 1. Review findings 1. Take action Notes: - Same 4 steps you saw for SAST, secret detection, dependency scanning --- # Enable container scanning
- **
Manual only
** - Edit `.gitlab-ci.yml` - Make sure you have a **test** stage defined - Add container scanning template
```yaml stages: - test include: - template: Security/Container-Scanning.gitlab-ci.yml ``` Notes: n/a --- # Configure container scanning
##
Sample options
- Remote image to scan - Remote container registry creds - Enable language package scanning
##
Edit `.gitlab-ci.yml`
- Set global variables - Override job definition and set job-scoped variables
```yaml container_scanning: variables: CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN: "false" ``` Notes: - Configure using same techniques you've seen for other scanners --- # Q&A
##
Container scanning
Notes: n/a --- # Lab 3 ##
Container scanning
- Package an app as a Docker image - Push the image to the container registry - Enable, configure, and run container
scanning on that image - View found vulnerabilities
Notes:
- Paste lab 3 guide: https://about.gitlab.com/handbook/customer-success/professional-services-engineering/education-services/secessentialshandson3.html - Set timer for 10, check in then, expect 15 mins for most people - Remind students they can look back to Lab 2 for instructions on disabling unused scanners to speed up their pipeline
--- # Module 5:
License compliance
**At the end of this module, you will be able to:**
- Explain what license compliance is - Use license compliance in a GitLab pipeline - View the different license compliance reports Notes: n/a --- # What is license compliance?
- **License compliance** = GitLab feature - **License scanning** = CI/CD job - Lists licenses of all dependencies
(and their dependencies) - You can optionally **allow/deny** each license type - **Blocks MRs** with denied licenses (overridable) - Uses open-source tool **License Finder**
Notes: - Reasons to deny a license: - military exclusion - export restrictions - copyleft (like GPL), etc. - Set approval rules in the **License-Check** ruleset that allows security officers to override license-related MR blocks. Will explain rulesets on next slides. --- # Steps for using
license compliance
1. Enable and configure license compliance 1. Run pipeline 1. Review findings 1. **
Take action
**
- **Dismiss/confirm/resolve** model isn't relevant - **Approve/deny** any licenses (optional) - **License-Check ruleset** overrides blocked MRs (optional)
Notes: - Taking action is different from other scanners - 2 options to unblock an MR that's blocked because of a denied license - Remove dependencies that have denied licenses - Override block with the **License-Check** ruleset --- # Enable license compliance
- **
Manual only
** - Edit `.gitlab-ci.yml` - Make sure you have a **test** stage defined - Add License Scanning template
```yaml stages: - test include: - template: Security/License-Scanning.gitlab-ci.yml ``` Notes: n/a --- # Configure license compliance
##
Sample options
- Language version - License Finder options
##
Set vars in `.gitlab-ci.yml`
- Global vars - Override job definition and
set job-scoped vars
```yaml license_scanning: variables: LM_PYTHON_VERSION: 2 ``` Notes: - Reminder: **License Finder** is the open-source tool used - You can set options that are passed through to License Finder ---
# License compliance demo Notes: ### Make new project
- Make new project: **License Compliance Demo**
### Unblock license compliance for the project - License compliance is blocked by default for all projects in the training environment. - We need to **unblock** it before we can **enable** it.
- **Settings > CI/CD > Variables > Expand > Add variable** - Set **LICENSE_MANAGEMENT_DISABLED** to be **<1 blank space>** - Uncheck **Protect variable** - **Add Variable**
### Make CI/CD config file
Create `.gitlab-ci.yml`: ```yaml stages: - test dummy-job: script: - echo "in dummy-job" include: - template: Security/License-Scanning.gitlab-ci.yml ```
- There are no dependencies for License Compliance to scan yet. ### Add dependencies to scan
Make `requirements.txt` in root dir: ```yaml pyparsing==2.4.7 # uses MIT license ```
- The comment in this line is just for us to read. License Compliance won't read it or use it in any way. ### View results
- In running pipeline, zoom in on license scanning job - Takes a minute to run b/c it pulls down and installs all the dependencies (to get at transitive dependencies) - When pipeline finishes, click **Licenses** tab on pipeline details page - Expected result: `MIT license is Uncategorized`
### Approve/deny our first license
- Click **Manage licenses** - Add rule to allow MIT License - Return to Pipeline details page > **Licenses** tab - Note that MIT License is now allowed
### Add new dependency on feature branch
- make **branch-a** - on **branch-a** add new requirement to `requirements.txt`: ```yaml screeps==0.1.5 # uses AGPL license ``` - commit change
### See licence compliance report in MR
- While pipeline runs, make MR for **branch-a** - When pipeline finishes **Pipeline Details > Licenses** - 5 uncategorized licenses come from screeps - Visit MR's license compliance pane - See 5 new licenses detected - doesn't mention MIT license, b/c that's not new to this branch
### Deny Screeps' license
- Copy name of screeps' AGPL license to clipboard - Click **Manage licenses** - Add new rule, paste screeps' AGPL license, mark as **deny** - **Pipeline details page > License:** show screeps is now out of compliance
### Is MR blocked by new screeps dependency?
- **MR license pane:** show screeps is out of compliance - MR is blocked from merge because of license compliance problems
- _If it doesn’t recognize Screeps as unauthorized, add the deny rule again, and view results again._ ### Unblock the MR - We must remove the new dependency OR override the block using License-Check ruleset - We'll do the latter
- **Settings > General > MR approvals > License-Check > Enable** - Add yourself to the list of approvers - Disable **Prevent MR approvals by author** - Save changes - Return to MR - Approve MR
- _Expect to see **Merge** button activate, but for some reason this doesn't happen in the training env_ --- # Q&A
##
License compliance
Notes: n/a --- # Lab 4 ##
License compliance
- Enable, configure, and run license
compliance for a Python project - Approve and deny licenses - Add approvers to the **License-Check**
ruleset
Notes:
- Paste lab 4 guide: https://about.gitlab.com/handbook/customer-success/professional-services-engineering/education-services/secessentialshandson4.html - Set timer for 10, check in then, expect 15 mins for most people - Remind students they can look back to Lab 2 for instructions on disabling unused scanners to speed up their pipeline
--- # Module 6:
Fuzz testing
**At the end of this module, you will be able to:**
- Explain what fuzz testing is - Explain why fuzz testing is valuable - Enable fuzz testing in a pipeline - View fuzz testing reports Notes: - Fuzz testing is the most interesting and most complicated GitLab scanner - Finds problems that QA teams can easily miss - Real-life examples of manual fuzz testing: - username with 200 characters shoves UI off screen - 4-digit ZIP (expain what this is for non-US students) - set password using Klingon unicode chars (which doesn't actually exist, but never mind) - going back and forth between pages in a wizard can cause a crash - Reminder: although fuzz testing is more about finding bugs than security vulnerabilities, many bugs can become security vulnerabilities if malicious actors know about them. --- # What is fuzz testing?
- Pass **random-ish data** to find bugs - Specializes in exotic edge cases - **Coverage-guided** (functions) vs **API** (endpoints) - Requires minor **coding** - Uses tool developed by GitLab - Slow and random, so can be run **async** - Found a bug? Job **fails** but pipeline **continues**
Notes: - Implications of non-deterministic nature - Might time out before finding an existing bug - Might find a bug after running for 1 second today, but find nothing after running for 1 hour tomorrow - Best practice: 10 min timeout on main/master, 60 min timeout on feature branches - Don't be afraid of the coding: it's largely cut & pasteable from examples - Async - Since it can for a long time without finding anything, you can run it asynchronously so it doesn't block pipelines - We don't demo async in class; GitLab docs tell you how to set it up with parent/child pipelines - Remember: other scanners pass if they complete, whether or not they find any problems. Not true of fuzz testing. --- # Steps for using fuzz testing
1. Enable and configure a fuzz test
for a **single function** 1. Run pipeline 1. Review findings 1. Take action Notes: - Similar to other scanners, except: - Enabling it is a little more complicated (will talk more on next slides) - Each fuzz test targets just **one** function, not your whole codebase - Each job **stops** when it finds 1 bug - Running pipeline multiple times might find more bugs - As already mentioned, bug finding is random: might miss some things --- # Fuzz test workflow
**CI/CD job**
**Fuzzer**
**Fuzz target** `IdAuthorTarget.py` `fuzz(random_bytes)`
**Code under test** `id_author(text)`
↓
`IdAuthorTarget.py`
↓
`99, 65, 50, 255`
↓
`"cA2"`
**Graceful?** Repeat.
**Non-graceful?** 🪲
Report bug
↑
`ValueError`
↑
`ValueError`
↑
`ValueError`
↑
Notes: Notes TBD --- # Fuzz testing with a corpus
📄 ⚙️ 📄
`customers.csv` --> `csv2html.py` --> `customers.html`
-
`dqykvmseioz`
-
`!@#$%^&*()_+`
-
`foo,bar,,baz`
- Corpus seeds fuzzer's random data - Valid data for mutation - Data that triggered bugs in the past - 2 purposes - Speed up bug-finding - Detect regressions - Lives in project repo or package registry - Optionally auto-updates
Notes: - **Use of corpus is optional** - **Code-under-test** is a fn called `csv2html` that converts CSV files into HTML tables - It gracefully handles any malformed input data except a **blank csv field** (i.e., two commas in a row) - The first two random byte series are handled gracefully; the third triggers a bug - Truly random data might take a **long time** to trigger the blank field bug - Add corpus with valid input so fuzzer can mutate that input and stumble on the blank field bug **much sooner** - Corpus can also include random data that triggered bugs in the past, to guard against **regressions** --- # Fuzz testing in action
Notes: - https://www.youtube.com/watch?v=4ROYvNfRZVU&ab_channel=GitLab -
If using Zoom, reshare screen with the "share audio" option **enabled**. When video is done, reshare screen with the "share audio" option **disabled**.
--- # Q&A
##
Fuzz testing
Notes: n/a --- # Lab 5 ##
Coverage-guided fuzz testing
- Write a Python function - Enable, configure, and run coverage-
guided fuzz testing for that function - View any bugs found
Notes:
- Paste lab 5 guide: https://about.gitlab.com/handbook/customer-success/professional-services-engineering/education-services/secessentialshandson5.html - Give students option of watching instructor demo, since it's kind of a complicated lab and their brains are tired - Set timer for 15, check in then, expect 20 mins for most people
--- # Module 7:
Infrastructure as code (IaC) scanning
**At the end of this module, you will be able to:**
- Explain what infrastructure as code (IaC) scanning is - Enable and configure IaC scanning in a GitLab pipeline - View the different IaC scanning reports Notes: n/a --- # What is IaC scanning?
- Finds
**known**
security vulnerabilities in
IaC configuration files - Supports configuration files for
Terraform, Ansible, Kubernetes, etc. - Uses open-source tool **KICS**
Notes: - Word "known" is important! Only finds problems that have already been discovered and catalogued somewhere by security experts. -
Show full list of supported technologies at `https://docs.gitlab.com/ee/user/application_security/iac_scanning/`
- GitLab IaC scanning (and KICS) only supports Terraform modules in the official Terraform registry at this time. Unofficial modules or Terraform modules in a custom registry are not scanned for vulnerabilities. - Link for KICS: https://github.com/Checkmarx/kics --- # Steps for using IaC scanning
1. Enable and configure IaC scanning 1. Run pipeline 1. Review findings 1. Take action Notes: - Same 4 steps as for almost all GitLab security scanners - We'll see each in action in a live demo --- # Enable IaC scanning ##
Manual
Edit `.gitlab-ci.yml` ```yaml stages: - test include: - template: Security/SAST-IaC.latest.gitlab-ci.yml ```
##
GUI
1. **Security & Compliance > Configuration** 1. **Infrastructure as Code (IaC) Scanning >
Configure with a merge request** 1. Merge auto-generated MR to edit `.gitlab-ci.yml` Notes: Requirements (from GitLab docs): - IaC Scanning runs in the test stage, which is available by default. If you redefine the stages in the .gitlab-ci.yml file, the test stage is required. - To run IaC scanning jobs, by default, you need GitLab Runner with the docker or kubernetes executor. If you’re using the shared runners on GitLab.com, this is enabled by default. - IaC scanning jobs require a Linux/amd64 container type. Windows containers are not yet supported. - If you use your own runners, make sure the Docker version installed is not 19.03.0. --- # Configure IaC scanning
##
Only 1 config option
- Use scanner based on a
FIPS image
##
Edit `.gitlab-ci.yml`
- Set global variable `SAST_IMAGE_SUFFIX` to
`-fips`
```yaml variables: SAST_IMAGE_SUFFIX: '-fips' include: - template: Security/SAST-IaC.latest.gitlab-ci.yml ``` Notes: - Only one configurable option, and it can be set with a global variable - FIPS = Federal Information Processing Standards. Some orgs might need this form of the scanner. ---
# IaC scanning demo Notes: TBD --- # Q&A
##
IaC scanning
Notes: n/a ---
# Final Q&A --- # Post-class survey
-
**What can we improve? What went well?**
- Please complete our 60-second survey - We read all survey responses carefully
`https://www.surveymonkey.com/r/proservtraining` Notes: -
paste URL into chat
https://www.surveymonkey.com/r/proservtraining
-
paste class name, instructor name, class date into chat
--- # GitLab Certified
Security Specialist Exam
- Score 80% on each of 2 parts - Written (knowledge) - Hands-On (skill) - 7 days to complete from 1st day of class - Use any resources - Retake as needed - Instructions in post-class email
Notes: - Probably be at least 1 question not covered in class, because different classes go in different directions. Don't worry! All answers are discoverable (see next bullet). - Use any reference materials - Any materials from the course - GitLab Docs - Google - No time limit per attempt (within 7 day limit) - Retake as many times as needed (within 7 day limit) - No proctoring - No trick questions - Let us know if any questions seem ambiguous or confusing - Do individually, not as a group ---
# Thank you!
`proserv-education@gitlab.com` `#GitLabEducationServices`