π Application Vulnerability Scanning
EXERCISE: Build a Continuous Integration Pipeline
- Create a Gitlab account
- Fork the repository: https://gitlab.com/onisimiacob/juice-shop
Note
- Add SSH credentials to the Gitlab Account following https://docs.gitlab.com/user/ssh/
- Clone repository locally.
- Create a DockerHub account: https://app.docker.com/signup
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.
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.
SAST Example Tools
Static analysis Security Testing (SAST) main goal is to reduce security findings over time and so that nothing gets deployed to production.
- Write secure code.
- Configure app and system securely.
We add tools to scan the static code, we have SAST tools based on the programming language. For our exercise, we can use a Njscan tool and another Semgrep tool that allows us to scan the local code (thats why it is called static) for vulnerabilities.
...
# Scan for NodeJS SAST vulnerabilies
njsscan:
stage: test
image: python
before_script:
- pip3 install --upgrade njsscan
script:
- njsscan --exit-warning . --sarif -o njsscan.sarif
allow_failure: true
# Scan with SemGrep
semgrep:
stage: test
image: semgrep/semgrep
variables:
SEMGREP_RULES: p/javascript
script:
- semgrep ci --json --output semgrep.json
allow_failure: true
...
SAST Scan Results
However, this will create different type of results such as:
- NjsScan: It is pretty usefull and easy to understand!
- SemGrep: On the other hand, some tools may detect more vulnerabilites but the output is humanly unreadable...

