SAST vs DAST: Understanding the Differences
Five years ago, I was building a personal finance tracking application as a side project. Like many developers, I was focused on features and functionality, thinking "I'll add security later when I have more users." That mindset changed when I decided to run my first security scan just out of curiosity.
In this post, I'll share my personal journey implementing both Static Application Security Testing (SAST) and Dynamic Application Security Testing (DAST) into my development workflow using GitLab, the lessons I learned, and how these complementary approaches transformed how I build applications.
The Day I Discovered My Code Had Problems
Before diving into security testing, my approach was typical of many solo developers: "Security is complex, I'll worry about it later." That mindset changed when I ran my first security scan on what I thought was a pretty solid personal project.
I quickly realized I needed a comprehensive approach to security:
Something to catch vulnerabilities in my code before I even deployed it
Something to test my running applications against real-world attack scenarios
Enter SAST and DAST – two powerful but fundamentally different security testing approaches that have become essential tools in my development toolkit.
SAST vs DAST: A Visual Comparison
Before diving deeper into implementation details, let me show you how SAST and DAST complement each other in our security testing approach:
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 my development workflow, it was an immediate eye-opener. During the first scan of my personal project's codebase, it found:
3 instances of hard-coded API keys (oops!)
2 potential SQL injection vulnerabilities
5 cross-site scripting (XSS) opportunities
Several unsafe input validation practices
Most importantly, these issues were caught before I deployed anything to production. As a developer, I appreciated how SAST became like having a security expert constantly reviewing my code and teaching me better practices.
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 my Node.js and Python projects:
# This is from my actual .gitlab-ci.yml file for personal projects
stages:
- test
- build
- deploy
# Include GitLab's predefined SAST template
include:
- template: Security/SAST.gitlab-ci.yml
variables:
# I configured this to scan my specific tech stack
SAST_EXCLUDED_PATHS: "node_modules, tests, dist"
SAST_ANALYZER_IMAGE_TAG: 3
SCAN_KUBERNETES_MANIFESTS: "true"
# My 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 to my production environment.
The Reality of Working with SAST
SAST became an invaluable part of my development process, but it wasn't without challenges:
False positives were frustrating at first: I had to tune the scanning rules for my codebase to reduce noise.
It slowed down my initial development: Until I realized it was actually saving me debugging time later.
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 explore the second security pillar: DAST.
DAST: Attacking My Own Applications Before Others 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 I first ran a DAST scan against my "secure" staging environment (which had passed all SAST checks), I was shocked to find:
An authentication bypass in my admin interface
Session management issues in my login flow
XSS vulnerabilities that weren't visible in the code alone
API endpoints returning more data than necessary
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 my GitLab CI/CD pipeline to scan my applications after deployment to staging:
# This goes in my .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"
# I 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:
# I send myself notifications after DAST scan completes
- |
if [ -f gl-dast-report.json ]; then
echo "Sending DAST results to my email..."
./scripts/notify_me.sh gl-dast-report.json
fi
I configured it to use authenticated scanning, which was crucial for testing my application's protected areas. The dynamic URL configuration using ${CI_COMMIT_REF_SLUG}
allows me to test each feature branch's deployment automatically.
DAST in Practice: A Real-World Win
Last year, my DAST scanner caught a business logic flaw in my personal finance app that would have allowed users to manipulate their transaction history. The vulnerability wasn't in my code per se, but in how different API endpoints interacted. SAST could never have caught this, but DAST found it because it tested the actual user workflow.
This discovery made me realize how valuable automated security testing really is, even for personal projects.
How I Combined SAST and DAST for Maximum Coverage
After running both tools for several months, I developed this workflow that has served me 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 me as a developer
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 me identify patterns and learning opportunities
This layered approach has drastically reduced vulnerabilities in my projects. In fact, when I recently had a penetration test done on one of my side projects, it found zero critical issues – something I never thought possible for a solo developer.
The Unexpected Business Benefits
The technical security improvements were expected, but what surprised me were the business benefits:
Faster development cycles: Counter-intuitively, adding security automation actually sped up my development by catching issues early
Personal confidence: I now deploy my side projects with confidence, knowing they've been thoroughly tested
Better coding habits: The constant feedback has made me write more secure code by default
Reduced stress: Fixing issues early in development is much less stressful than discovering them in production
My Advice for Your Security Testing Journey
If you're looking to implement SAST and DAST in your own projects, 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 - False alarms will quickly kill your motivation
Learn from each finding - The tools work best when you understand what they're catching
Make it part of your routine - Integrate security checks into your regular development workflow
Celebrate the catches - Track "vulnerabilities prevented" and feel good about the problems you avoided
Final Thoughts: Security as a Personal Practice
Five years after starting my security testing journey, I no longer see security testing as an additional step in development—it's simply how I build software. SAST and DAST have become as fundamental to my process as version control.
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