CoursesSecure CI/CD with GitLabSecurity scanning stages

DAST & the scan pipeline

Test the running app; wire it all together.

Advanced12 min · lesson 12 of 17

Every scanner so far is static — it reads code, dependencies, or an image at rest. Dynamic Application Security Testing (DAST) is the opposite: it deploys the running application to a test environment and attacks it like an outsider would, probing live endpoints for issues that only appear at runtime — authentication flaws, injection reflected in responses, misconfigured headers, exposed admin paths. OWASP ZAP is the common engine, and GitLab wraps it in a template.

THE DEFENSE-IN-DEPTH SCAN PIPELINE
1test
SAST + secret detection + SCA (source & deps)
2build
build the container image
3scan-image
Trivy scans image, gates the registry push
4deploy-staging
deploy a live test instance
5dast
OWASP ZAP probes the running staging app
6deploy-prod
manual, protected environment
Each stage catches what the others miss; every stage reports fully but gates only on the actionable subset.
.gitlab-ci.yml
include:
- template: DAST.gitlab-ci.yml
dast:
variables:
DAST_WEBSITE: https://staging.acme.internal # a deployed test instance
stage: dast
# runs after deploy-to-staging; probes the live app, not the source

DAST needs a running target — and time

Because it attacks a live app, DAST runs late (after a deploy to staging) and is slower than static scans — a full active scan can take many minutes. So it usually does not gate every merge request; the common pattern is a fast passive/baseline scan on MRs and a full active scan nightly or before a release. It complements static analysis rather than replacing it: SAST sees the code DAST cannot reach, DAST sees the runtime behavior SAST cannot predict.

Wiring the whole scan pipeline together

Put the pieces in order and you have a defense-in-depth pipeline: SAST, secret detection, and SCA run early on the source and dependencies; the image scan runs after build and gates the push; DAST runs after the staging deploy. Each stage catches what the others miss, each reports fully and gates on the actionable subset, and together they mean a change is checked five ways before it can reach production.

.gitlab-ci.yml
stages: [test, build, scan-image, deploy-staging, dast, deploy-prod]
# test: sast, secret-detection, dependency-scanning (source + deps)
# scan-image: trivy image (gate the push)
# dast: probe the staging deploy
# deploy-prod: manual, protected environment (next section)
Scanning finds; it does not fix
A pipeline full of green scanners is not "secure" — it means nothing critical was found this run. The value is only realized when findings are triaged and fixed, and when the gates actually block on real issues rather than being set to warn-and-ignore. Wire the scanners in, keep them tuned and trusted, and treat their output as a work queue, not a checkbox.