100x
cheaper to fix a vulnerability in design than in production -- IBM Systems Sciences Institute
76%
of applications contain at least one vulnerability at first scan (Veracode State of Software Security 2025)
SAST + SCA
combination catches 68% of vulnerabilities before code reaches production when integrated into CI/CD pipelines

A Secure Software Development Lifecycle (SSDLC) embeds security controls and checkpoints into every phase of software development -- from requirements gathering through deployment and maintenance. The alternative is the traditional model: write code, then hand it to security for review before release. That model creates bottlenecks, produces findings too late to fix cheaply, and treats security as a gate rather than a capability. This guide covers how to implement a practical SSDLC that accelerates secure development rather than slowing it down.

Phase 1: Security Requirements and Risk Classification

Security requirements define what the software must do (and must not do) from a security perspective. Without them, developers build features without knowing the security constraints.

Security requirements sources:

  • Regulatory and compliance: PCI DSS, HIPAA, GDPR, SOC 2 -- each mandates specific technical controls (encryption, access logging, data retention)
  • Organizational security policy: Approved algorithms, prohibited functions (no MD5, no SHA-1, no eval())
  • Business risk: What happens if this feature is compromised? Data breach, financial fraud, service disruption?
  • User trust model: Who uses this feature? Internal employees vs. anonymous public users have different threat models

Application risk classification:

Classify each application to determine the intensity of security controls required:

TierCriteriaSecurity Requirements
CriticalHandles PII, PAN, PHI, or credentials; externally exposed; revenue-criticalFull SSDLC, mandatory threat model, annual pentest, weekly DAST
HighInternal tools with sensitive data access; authenticated external servicesThreat model for new features, quarterly DAST, SAST in CI
MediumInternal tools, limited data sensitivitySAST in CI, annual security review
LowInternal utilities, no sensitive dataDependency scanning only

Security user stories:

Capture security requirements as user stories in your backlog:

  • "As the security team, we need all authentication events logged with user ID, IP, timestamp, and outcome so that we can detect and investigate anomalous access."
  • "As a user, my session token must expire after 30 minutes of inactivity so that my account cannot be accessed from an unattended device."
  • "As the compliance team, all credit card data must be encrypted with AES-256 at rest using a KMS-managed key so that stolen database files cannot expose PAN."

Security user stories prevent security requirements from being treated as optional -- they are tracked in the same backlog as features and must be accepted by the same definition of done.

Phase 2: Threat Modeling in Agile Sprints

Threat modeling identifies how an attacker might abuse your design before a line of code is written. In an agile environment, it should happen at two levels: a high-level model at project kickoff and lightweight feature-level modeling per sprint.

Threat modeling at project kickoff (STRIDE):

STRIDE is the most widely used enterprise threat modeling framework. For each data flow in your architecture diagram, ask:

ThreatQuestionExample Finding
SpoofingCan an attacker impersonate a user or system?API endpoint trusts X-Forwarded-For header without validation
TamperingCan an attacker modify data in transit or at rest?Order total recalculated client-side, not server-side
RepudiationCan users deny performing actions?No audit log for administrative operations
Information DisclosureCan data leak to unauthorized parties?Error messages expose stack traces with DB connection strings
Denial of ServiceCan an attacker exhaust resources?No rate limiting on authentication endpoint
Elevation of PrivilegeCan an attacker gain unintended permissions?IDOR vulnerability on document ID parameter

Tools for threat modeling:

  • OWASP Threat Dragon: Free, web-based, produces DFDs with threats annotated
  • Microsoft Threat Modeling Tool: Free, Windows-based, STRIDE-focused with automated threat suggestions
  • IriusRisk: Commercial, integrates with Jira, generates requirements automatically from architecture diagrams
  • Threagile: Open-source, YAML-based, generates threat models as code (ideal for DevSecOps pipelines)

Lightweight sprint-level threat modeling:

For each new significant feature in a sprint, run a 30-minute threat model session:

  1. Draw a simple data flow diagram (5-10 minutes)
  2. Walk through each data flow and ask "what is the worst thing an attacker can do here?" (15 minutes)
  3. Create security user stories for each finding (10 minutes)

This catches design-level issues before implementation and typically takes less time than the code review that would find the same issues later.

Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

Phase 3: Secure Coding Standards and Developer Tooling

Secure coding standards define the implementation-level rules developers must follow. The most effective standards are language-specific, integrated into the IDE, and enforced automatically in CI.

Security-relevant coding rules by category:

Input validation and output encoding:

  • Validate all input against an allowlist (not a denylist)
  • Parameterize all database queries -- never concatenate user input into SQL
  • Encode all output in the correct context (HTML encoding, JavaScript encoding, URL encoding)
  • Validate file uploads: type, size, filename, content

Authentication and session management:

  • Use established libraries for authentication -- never implement custom auth
  • Store passwords with Argon2id (preferred), bcrypt (acceptable), or scrypt -- never with MD5, SHA-1, or unsalted SHA-256
  • Generate session tokens with cryptographically secure random number generators (CSPRNG)
  • Invalidate sessions on logout and privilege change

Cryptography:

  • Use AES-256-GCM for symmetric encryption -- never implement custom ciphers
  • Use the platform TLS implementation for transport security -- never roll your own
  • Never hard-code secrets, keys, or passwords in source code
  • Use secure key storage (KMS, Vault) -- never store keys in application config files

Error handling:

  • Return generic error messages to users; log detailed errors server-side with correlation IDs
  • Never expose stack traces, database errors, or internal paths to users

IDE and pre-commit security:

Enforce security rules before code is committed:

# Semgrep pre-commit hook (catches security anti-patterns at save time)
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/returntocorp/semgrep
    rev: 'v1.70.0'
    hooks:
      - id: semgrep
        args: ['--config', 'p/security-audit', '--config', 'p/owasp-top-ten', '--error']
# Install and run
pip install pre-commit
pre-commit install
pre-commit run --all-files

Phase 4: SAST, DAST, and SCA in CI/CD

Automated security testing in CI/CD provides continuous feedback without requiring manual security reviews for every pull request.

SAST (Static Application Security Testing):

SAST analyzes source code for security vulnerabilities without executing it. Best integrated at the pull request stage to catch issues before merge.

ToolLanguage SupportStrength
Semgrep30+ languagesFast, rule-as-code, open-source rules via registry
CodeQL (GitHub Advanced Security)10+ languagesDeep dataflow analysis, finds complex injection patterns
Checkmarx30+ languagesEnterprise, SAST + DAST + SCA combined
Veracode20+ languagesEnterprise, binary analysis (no source required)
SonarQube30+ languagesDeveloper-friendly, IDE integration, free community edition

GitHub Actions SAST pipeline (Semgrep + CodeQL):

name: Security Scan
on: [pull_request]
jobs:
  semgrep:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: returntocorp/semgrep-action@v1
        with:
          config: >-
            p/security-audit
            p/owasp-top-ten
            p/secrets
          auditOn: push
  codeql:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: javascript, python
      - uses: github/codeql-action/autobuild@v3
      - uses: github/codeql-action/analyze@v3

SCA (Software Composition Analysis):

SCA identifies vulnerable open-source dependencies. Run on every dependency update and in CI.

# Trivy for dependency scanning
trivy fs --scanners vuln --severity HIGH,CRITICAL .

# Snyk for developer-friendly output with remediation suggestions
snyk test --severity-threshold=high

# OWASP Dependency-Check (free, supports Java, .NET, Node, Python)
dependency-check.sh --project "MyApp" --scan ./

DAST (Dynamic Application Security Testing):

DAST tests the running application from the outside, finding runtime vulnerabilities that SAST misses (authentication bypass, session management, business logic flaws).

Integrate DAST in a staging environment as part of the deployment pipeline:

# OWASP ZAP baseline scan against staging
docker run -v $(pwd):/zap/wrk/:rw   ghcr.io/zaproxy/zaproxy:stable zap-baseline.py   -t https://staging.yourapp.com   -r zap-report.html   -x zap-report.xml   -I  # ignore warnings, only fail on errors

# ZAP full scan (more thorough, slower)
docker run ghcr.io/zaproxy/zaproxy:stable zap-full-scan.py   -t https://staging.yourapp.com   -r full-scan-report.html

Security gate thresholds:

Finding SeveritySASTSCADAST
CriticalBlock PR mergeBlock deploymentBlock deployment
HighBlock PR mergeBlock deploymentRequired review before deployment
MediumFlag for reviewFlag for reviewFlag for review
LowInformationalInformationalInformational

Phase 5: Security Testing and Penetration Testing Cadence

Automated tooling catches common vulnerability classes but misses business logic flaws, complex authentication bypasses, and chained attack scenarios. Manual security testing fills this gap.

Security testing types by SDLC phase:

Testing TypeWhenPerformed ByFinds
Design reviewBefore codingInternal AppSecArchitecture flaws, missing controls
SASTPer PRCI/CD automatedCode-level vulnerabilities
SCAPer dependency updateCI/CD automatedKnown CVEs in dependencies
Security code reviewMajor featuresInternal AppSec or externalLogic flaws SAST misses
DASTPre-release, stagingCI/CD + AppSecRuntime vulnerabilities
Penetration testPre-launch, annualExternal pentest firmComplex attack chains, business logic
Bug bountyContinuous (post-launch)External researchersLong-tail vulnerabilities

Penetration testing cadence by application tier:

TierInternal Security ReviewExternal Pentest
CriticalEvery major releaseAnnual + post-major-change
HighEvery major releaseAnnual
MediumAnnualBiennial
LowOn major architecture changeNot required

Pre-pentest checklist:

Before engaging an external pentest firm:

  • SAST and SCA findings are triaged and critical/high issues remediated or risk-accepted
  • Staging environment matches production architecture (same auth flows, same services)
  • Test accounts are provisioned at each privilege level (unauthenticated, regular user, admin)
  • Scope document defines in-scope URLs, endpoints, IP ranges, and out-of-scope systems
  • Rules of engagement define testing hours and contact procedures

Tracking findings through remediation:

All security findings (from any tool or manual test) should enter a unified tracking system (Jira, DefectDojo, or ThreadFix) with:

  • Severity and CVSS score
  • SLA for remediation by severity tier (Critical: 24h, High: 7d, Medium: 30d, Low: 90d)
  • Owner (the development team responsible for the component)
  • Risk acceptance workflow for findings that cannot be remediated within SLA

Measuring SSDLC Maturity

SSDLC programs need metrics to demonstrate progress and identify gaps.

OWASP SAMM (Software Assurance Maturity Model):

SAMM provides a framework for measuring SSDLC maturity across 5 business functions and 15 security practices, each scored 0-3:

Business FunctionPractices
GovernanceStrategy, Policy, Education
DesignThreat Assessment, Security Requirements, Secure Architecture
ImplementationSecure Build, Secure Deployment, Defect Management
VerificationArchitecture Assessment, Requirements Testing, Security Testing
OperationsIncident Management, Environment Management, Operational Management

Run a SAMM assessment annually. Target progression: Level 1 (baseline controls) in Year 1; Level 2 (structured program) in Year 2-3; Level 3 (optimized, measured) for organizations with dedicated AppSec teams.

Key metrics for SSDLC reporting:

MetricTargetMeasurement
SAST coverage100% of Tier 1-2 apps% of repos with SAST in CI
SCA coverage100% of all apps% of repos with dependency scanning
Mean Time to Remediate (MTTR) by severityCritical <24h, High <7dDefect tracker data
Security debt (open findings >SLA)Trending down quarterlyDefect tracker
% of features with threat model100% of new Tier 1 featuresSprint documentation
Security training completion100% of developers annuallyLMS data

The bottom line

A Secure SDLC is not a single tool or process -- it is a collection of lightweight controls embedded at each development phase that collectively prevent the majority of production vulnerabilities. Start with the highest-leverage activities: SCA in CI (fastest to deploy, catches supply chain risk immediately), security user stories in sprint planning (shifts requirements left), and threat modeling for new Tier 1 features. Add SAST and DAST as the program matures. Measure maturity annually with OWASP SAMM and track MTTR to demonstrate progress to leadership.

Frequently asked questions

What is the difference between SAST, DAST, and SCA?

SAST (Static Application Security Testing) analyzes source code without executing it, finding vulnerabilities like SQL injection, XSS, and hardcoded secrets in the codebase itself. DAST (Dynamic Application Security Testing) tests the running application from the outside, simulating attacker behavior against the live app -- it finds runtime issues SAST misses like authentication bypass, session management flaws, and server misconfiguration. SCA (Software Composition Analysis) scans open-source dependencies for known CVEs -- it does not analyze your code, only the libraries you import. A complete toolchain uses all three: SCA catches supply chain risk, SAST catches implementation flaws, DAST catches runtime vulnerabilities.

How do we do threat modeling in an agile environment without slowing down sprints?

Lightweight agile threat modeling takes 30-60 minutes per significant feature, not the multi-day workshops associated with waterfall projects. The approach: at sprint planning when a significant new feature is introduced, spend 30 minutes drawing a simple data flow diagram and asking 'what can go wrong?' for each data flow. Use STRIDE as a checklist. Any identified risks become security user stories in the backlog. For the majority of sprint work (bug fixes, UI changes, minor features), a full threat model is not required -- reserve it for new authentication flows, new data stores, new external integrations, and privilege-changing operations.

What is the most impactful first step for a team with no SSDLC today?

Start with SCA (Software Composition Analysis) dependency scanning in CI. It takes under an hour to configure, requires no code changes, produces immediate actionable findings, and addresses supply chain vulnerability risk -- one of the most exploited attack vectors. Configure Dependabot (free in GitHub) or Snyk (free tier) to scan your repositories and open PRs for dependency updates with known CVEs. This alone will find critical vulnerabilities in most codebases and builds the habit of treating security findings as part of normal development workflow, not a separate process.

How do we handle false positives in SAST tools without ignoring real findings?

False positive management is the most common reason SAST programs fail -- developers learn to ignore all findings when too many are false positives. Effective approach: (1) Start with a curated ruleset rather than all rules -- Semgrep's p/security-audit and p/owasp-top-ten have been tuned for low false positive rates; (2) Use inline suppression comments only for documented false positives with a justification (for example, a finding on a parameterized query that is incorrectly flagged as SQL injection); (3) Track false positive rate per rule -- rules with >50% false positive rate should be disabled or tuned; (4) Require all suppressions to be reviewed in code review -- no self-approving suppressions for security findings.

When should we do a penetration test vs. relying on automated SAST/DAST?

Automated tools cover common, well-defined vulnerability classes efficiently but miss business logic flaws, complex multi-step attack chains, and vulnerabilities that require understanding the application's intended behavior. Manual penetration testing is required for: pre-launch of Tier 1 applications (payment flows, authentication systems, data stores); post-major-architecture changes; annually for externally-exposed critical applications; and any time you have reason to believe the automated toolchain has gaps. Think of it as layers: SAST/SCA run on every commit (high frequency, low depth), DAST runs on every deploy to staging (medium frequency, medium depth), and penetration tests run annually or pre-launch (low frequency, high depth).

What is OWASP SAMM and how do we use it to measure our SSDLC maturity?

OWASP SAMM (Software Assurance Maturity Model) is a framework for measuring the maturity of your software security program across 5 business functions (Governance, Design, Implementation, Verification, Operations) and 15 security practices. Each practice is scored 0-3. Run a SAMM assessment by working through the SAMM toolbox (free at owaspsamm.org) -- it takes 4-8 hours for a thorough assessment of a medium-sized organization. The output shows your current state, identifies gaps, and provides a prioritized roadmap to the next maturity level. Use it as an annual benchmark: share the results with engineering leadership to demonstrate program progress and justify security investment.

Sources & references

  1. OWASP SAMM (Software Assurance Maturity Model)
  2. NIST SP 800-218: Secure Software Development Framework (SSDF)
  3. Semgrep Security Rules
  4. OWASP Web Security Testing Guide

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, weekly, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals weekly.

Free Brief

The Mythos Brief is free.

AI that finds 27-year-old zero-days. What it means for your security program.

Joins Decryption Digest. Unsubscribe anytime.

Daily Briefing

Get briefings like this every morning

Actionable threat intelligence for working practitioners. Free. No spam. Trusted by 50,000+ SOC analysts, CISOs, and security engineers.

Unsubscribe anytime.

Mythos Brief

Anthropic's AI finds zero-days your scanners miss.