Skip to content

πŸ”Ž Application Vulnerability Scanning

βœ… EXERCISE: Build a Continuous Integration Pipeline

For this exercise, go to the repository setComparisontings and set juice-shop > CI/CD Settings and set CI/CD configuration file to .gitlab/.gitlab-ci.yml, otherwise the pipeline will try to be created on root folder.

INSECURE PIPELINE! Avoid saving passwords as variables!

variables:
  IMAGE_NAME: onisimiacob/demo-app
  IMAGE_VERSION: juice-shop-1.0

stages:
  - cache
  - test
  - build

# Improove build times with a cache task that saves the dependencies as an artifact
create_cache:
  image: node:18-bullseye
  stage: cache
  script:
    - yarn install --ignore-engines 
  cache:
    key:
      files:
        - yarn.lock
    paths:
      - node_modules
      - yarn.lock
      - .yarn
    policy: pull-push

# Test using the cache to speedup testing
yarn_test:
  image: node:18-bullseye
  stage: test
  script:
    - yarn install --ignore-engines # fix The engine "node" is incompatible with this module. Expected version "20 || >=22". Got "18.20.8"
    - yarn test
  cache:
    key:
      files:
        - yarn.lock
    paths:
      - node_modules
      - yarn.lock
      - .yarn
    policy: pull

# Build the docker image
build_image:
  stage: build
  image: docker:24
  services:
    - docker:24-dind
  variables:
    DOCKER_USER: onisimiacob
    DOCKER_PASS: 1234567890!
  before_script:
    - echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
  script:
    - docker build -t $IMAGE_NAME:$IMAGE_VERSION .
    - docker push $IMAGE_NAME:$IMAGE_VERSION

SECURE PIPELINE!

Instead of only building the application, we DevSecOps integrates security through the workflow. Such vulnerabilities could be hardcoded passwords, connection strings (secrets). This is a leaky asset, and you never know where it ends up.

Secret scanning with Gitleaks

Lightweight open-source application for git repositories that detects over 160 secret types, new types added all the time.

Running this command inside the git repository, will mount the "." local path with /path inside the docker and allow us to scan for all vulnerabilities.

In addition add --verbose flag at the end to see on screen what are the encountered vulnerabilites.

docker run -v .:/path zricethezav/gitleaks:latest detect --source="/path" #--verbose to see vulnearbilities on screen


    β—‹
    β”‚β•²
    β”‚ β—‹
    β—‹ β–‘
    β–‘    gitleaks

7:11PM INF 132 commits scanned.
7:11PM INF scanned ~9214215 bytes (9.21 MB) in 1.93s
7:11PM WRN leaks found: 42

Pre-Commit hook for secret scanning

We can add hooks such as pre-commits which are actions that gets executed before a push is made to remote. These hooks are stored on .git/hooks/pre-commits

Note

It can be easily be automated with pre-commit which is a python package.

False Positives

First, we cannot block the pipeline deployment with tools that we are not yet sure on how they may behave. This is why we need to allow builds to continue. This can be achieved with pipeline flags such as:

gitleaks:
  stage: test
  image:
    name: zricethezav/gitleaks:latest
    entrypoint: [""]
  script:
    - gitleaks detect --verbose --source .
  allow_failure: true # <- This allows the task to fail but continue!

Pipeline Variables

On the Gitlab Project you can head to juice-shop > CI/CD Settings > Variables > Add variable > Key: DOCKER_PASS; Value: my_pass.

Note

Only DevOps or repository Admins/Owners (1 or 2 team members) should have access to the repository settings to add or modify variables.

...
  variables:
   DOCKER_USER: onisimiacob
   DOCKER_PASS: 1234567890! # BAD PRACTICE!!!
...

Warning

We should CHANGE THE PASSWORD as we already gitted the password. Gitleaks searches all commits, so we need to recreate a new password to fully fix the issue.

...
  variables:
   DOCKER_USER: $DOCKER_USER
   DOCKER_PASS: $DOCKER_PASS # GOOD PRACTICE :)
...