SAST vs DAST: Understanding the Differences
Four years ago, I was working at a fintech startup when we experienced a significant security breach. An SQL injection vulnerability in one of our public API led to a data leak that cost us both money and reputation. That was my wake-up call to get serious about application security testing.
In this post, I'll share my personal journey implementing both Static Application Security Testing (SAST) and Dynamic Application Security Testing (DAST) into our DevSecOps pipeline using GitLab, the lessons I learned, and how these complementary approaches transformed our security posture.
The Day I Learned Security Can't Wait
Before our security incident, our approach was typical of many startups: "We'll add security later when we have more resources." That mindset changed overnight when I had to explain to our CEO why customer data was exposed.
I quickly realized we needed a two-pronged approach:
Something to catch vulnerabilities in our code before it's even committed
Something to test our running applications against real-world attack scenarios
Enter SAST and DAST โ two powerful but fundamentally different security testing approaches that have become cornerstones of our DevSecOps strategy.
SAST: Finding Vulnerabilities in Code Before They Become Problems
Static Application Security Testing (SAST) analyzes source code without running the application. Think of it as a security-focused code review that never gets tired.
Why I Love SAST
When I implemented SAST in our team's workflow, it was an immediate eye-opener. During the first scan of our codebase, it found:
12 instances of hard-coded credentials
8 potential SQL injection vulnerabilities
15 cross-site scripting (XSS) opportunities
Several unsafe deserialization practices
Most importantly, these issues were caught before the code was ever deployed. As a developer at heart, I appreciated how SAST became like a security mentor, teaching us secure coding practices through its feedback.
My GitLab SAST Implementation
After trying several tools, I settled on GitLab's built-in SAST capabilities. Here's exactly how I configured it for our NodeJS and Python applications:
# This is from our actual .gitlab-ci.yml file
stages:
- test
- build
- deploy
# Include GitLab's predefined SAST template
include:
- template: Security/SAST.gitlab-ci.yml
variables:
# We configured this to scan our specific tech stack
SAST_EXCLUDED_PATHS: "node_modules, tests, dist"
SAST_ANALYZER_IMAGE_TAG: 3
SCAN_KUBERNETES_MANIFESTS: "true"
# Our custom job that runs after the SAST scans
sast_review:
stage: test
needs: ["sast"]
script:
- echo "Checking SAST results for blockers..."
- if [ -f gl-sast-report.json ]; then
python3 ./scripts/check_sast_blockers.py gl-sast-report.json;
else
echo "No SAST report found";
exit 1;
fi
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
The check_sast_blockers.py
script I wrote parses the SAST results and fails the pipeline if any critical vulnerabilities are found. This ensures that dangerous code never makes it through code review.
The Reality of Working with SAST
SAST became an invaluable part of our development process, but it wasn't without challenges:
False positives were frustrating at first: We had to tune the scanning rules for our codebase to reduce noise.
Developers initially resisted the additional step: Until they saw how SAST caught issues before QA sent them back with bug reports.
Some complex vulnerabilities were missed: SAST couldn't detect certain logic flaws or issues that only appear at runtime.
That last point led me to our second security pillar: DAST.
DAST: Attacking My Own Applications Before Hackers Could
Dynamic Application Security Testing (DAST) analyzes applications while they're running, simulating real attacks against your system. If SAST is like a code reviewer, DAST is like an ethical hacker on your team.
The DAST Revelation
When we first ran a DAST scan against our "secure" staging environment (which had passed all SAST checks), I was shocked to find:
An authentication bypass vulnerability in our admin panel
Session fixation possibilities in our login flow
XSS vulnerabilities that weren't visible in the code alone
API endpoints returning excessive data
Many of these issues resulted from complex interactions between components or runtime configurations โ things SAST simply couldn't see by looking at code alone.
My GitLab DAST Implementation
Here's how I set up DAST in our GitLab CI/CD pipeline to scan our applications after deployment to staging:
# This goes in our .gitlab-ci.yml file
include:
- template: Security/DAST.gitlab-ci.yml
stages:
- build
- test
- deploy
- dast
variables:
DAST_WEBSITE: https://staging-${CI_COMMIT_REF_SLUG}.example.com
DAST_AUTH_URL: https://staging-${CI_COMMIT_REF_SLUG}.example.com/login
DAST_USERNAME: $DAST_TEST_USER
DAST_PASSWORD: $DAST_TEST_PASSWORD
DAST_AUTH_VERIFICATION_URL: https://staging-${CI_COMMIT_REF_SLUG}.example.com/dashboard
DAST_BROWSER_SCAN: "true"
# We customized the DAST job to run only after successful deployment
dast:
stage: dast
variables:
GIT_STRATEGY: none
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
# We send notifications after DAST scan completes
- |
if [ -f gl-dast-report.json ]; then
echo "Sending DAST results to security team..."
./scripts/notify_security_team.sh gl-dast-report.json
fi
I configured it to use authenticated scanning, which was crucial for testing our application's protected areas. The dynamic URL configuration using ${CI_COMMIT_REF_SLUG}
allows us to test each feature branch's deployment automatically.
DAST in Practice: A Real-World Win
Last year, our DAST scanner caught a severe business logic flaw that would have allowed users to bypass payment verification. The vulnerability wasn't in our code per se, but in how different microservices interacted. SAST could never have caught this, but DAST found it because it tested the actual flow a user would take.
The security team estimated this catch alone saved us from potential losses exceeding $100,000.
How I Combined SAST and DAST for Maximum Coverage
After running both tools for several months, I developed this workflow that has served us well:
SAST runs on every commit - catching issues at the earliest possible stage
SAST findings are reviewed in merge requests - creating a continuous learning loop for developers
DAST runs after staging deployment - catching runtime and integration issues
Critical DAST findings block production deployment - preventing vulnerable code from reaching users
Weekly security review of all findings - helping us identify patterns and training opportunities
This layered approach has drastically reduced our vulnerability count. In fact, our most recent external penetration test found zero critical issues โ a first for our company.
The Unexpected Business Benefits
The technical security improvements were expected, but what surprised me were the business benefits:
Faster releases: Counter-intuitively, adding security automation actually sped up our release cycle by reducing last-minute security issues
Customer trust: We now confidently share our security practices with customers, becoming a competitive advantage
Regulatory compliance: Our documented security testing has streamlined SOC 2 and PCI DSS certification processes
Reduced remediation costs: Fixing issues early in development is exponentially cheaper than emergency patches
My Advice for Your Security Testing Journey
If you're looking to implement SAST and DAST in your organization, here's what I wish someone had told me:
Start small but start now - Even basic scanning is better than nothing
Tune out false positives aggressively - Developer fatigue from false alarms is a real risk
Invest in developer security training - The tools work best when developers understand the vulnerabilities
Create a "security champion" role - We rotate this responsibility among team members quarterly
Celebrate security wins - We track "vulnerabilities prevented" as a key metric and celebrate improvements
Final Thoughts: Security as a Journey
Three years after our security incident, I no longer see security testing as an additional step in developmentโit's simply how we build software. SAST and DAST have become as fundamental to our process as unit testing.
If you're just starting your AppSec journey, remember that perfect is the enemy of good. Start with basic GitLab SAST integration, add DAST when you're ready, and continuously improve your approach.
The peace of mind that comes from knowing you've systematically reduced your attack surface is well worth the investment.
Last updated