What Is Secure SDLC?
Secure Software Development Lifecycle (Secure SDLC) is the practice of integrating security activities into every phase of the software development process, rather than treating security as a separate phase or an afterthought. The goal is to identify and fix vulnerabilities as early as possible when they are cheapest to remediate.
The Cost of Late Fixes
| Phase Found | Relative Fix Cost |
|-------------|-------------------|
| Requirements | 1x |
| Design | 6x |
| Implementation | 15x |
| Testing | 40x |
| Production | 100x+ |
Finding a vulnerability during requirements costs virtually nothing to fix. Finding the same vulnerability after deployment can cost millions in incident response, legal fees, and reputational damage.
Phase 1: Requirements and Planning
Security Requirements Gathering
### Security Requirements Template
**Feature:** User Authentication
**Security Requirements:**
- [SR-001] Passwords must be hashed with Argon2id
- [SR-002] Rate limit login attempts to 5 per 15 minutes
- [SR-003] MFA must be available for all accounts
- [SR-004] Session tokens must expire after 15 minutes
- [SR-005] Failed login attempts must be logged to SIEM
Abuse Case Development
Document how attackers might abuse a feature:
| Use Case | Abuse Case |
|----------|------------|
| User resets password | Attacker triggers unlimited reset emails |
| File upload avatar | Attacker uploads executable masquerading as image |
| Search functionality | Attacker injects SQL via search query |
Phase 2: Design
Threat Modeling with STRIDE
| Category | Threat | Example |
|----------|--------|---------|
| Spoofing | Impersonating a user | Forged JWT token |
| Tampering | Modifying data | SQL injection |
| Repudiation | Denying actions | Missing audit logs |
| Information Disclosure | Leaking data | Exposed API keys |
| Denial of Service | Overloading service | Rate limit bypass |
| Elevation of Privilege | Gaining unauthorized access | IDOR vulnerability |
Creating a Threat Model
# Structured threat model entry
threat_model = {
"id": "TM-001",
"feature": "Payment Processing",
"diagram": "https://miro.com/board/payment-flow",
"entries": [
{
"threat": "Credit card data intercepted in transit",
"category": "Information Disclosure",
"risk": "Critical",
"mitigation": "TLS 1.3 with HSTS",
"status": "Implemented"
},
{
"threat": "Payment amount modified during API call",
"category": "Tampering",
"risk": "High",
"mitigation": "Request signing with HMAC",
"status": "Planned"
}
]
}
Phase 3: Implementation
Secure Coding Standards
// Secure coding checklist enforced via ESLint
// GOOD: Parameterized query
db.execute('SELECT * FROM users WHERE id = $1', [userId]);
// BAD: String concatenation
db.execute(`SELECT * FROM users WHERE id = ${userId}`);
// GOOD: Input validation
const id = parseInt(userInput, 10);
if (isNaN(id)) throw new Error('Invalid ID');
// GOOD: Output encoding
res.send(encodeURIComponent(userProvidedUrl));
// GOOD: Secure defaults
const cookie = sessionCookie.serialize('sid', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 900000
});
Pre-Commit Hooks
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: detect-private-key
- id: check-added-large-files
- id: check-merge-conflict
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
- repo: https://github.com/returntocorp/semgrep
rev: v1.54.0
hooks:
- id: semgrep
args: ['--config=auto', '--error']
Phase 4: Testing
SAST (Static Application Security Testing)
# GitHub CodeQL configuration
name: "CodeQL"
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
matrix:
language: ['javascript', 'python']
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
- uses: github/codeql-action/analyze@v3
Dependency Scanning
name: Dependency Security Scan
on:
schedule:
- cron: '0 6 * * 1' # Every Monday
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm audit --audit-level=high
- name: Check for known vulnerabilities
run: |
npx snyk test --severity-threshold=high
npx snyk monitor
DAST (Dynamic Application Security Testing)
# Run OWASP ZAP against staging environment
docker run -v $(pwd):/zap/wrk:rw \
-t ghcr.io/zaproxy/zaproxy:stable \
zap-full-scan.py \
-t https://staging.example.com \
-r zap-report.html \
-I # Include passive scan warnings
Phase 5: Deployment
Security Gates
# Deployment approval gates
environment:
name: production
required_approvals: 2
security_gates:
- name: SAST Scan
status: passed
- name: Dependency Scan
status: passed
- name: Container Scan
status: passed
- name: DAST Scan (Staging)
status: passed
- name: Manual Security Review
status: approved
Phase 6: Operations
Vulnerability Management
| Severity | Fix Timeline | Response |
|----------|-------------|----------|
| Critical | 24 hours | Hotfix deployment |
| High | 7 days | Next minor release |
| Medium | 30 days | Next regular release |
| Low | 90 days | Backlog |
Incident Response Plan
1. Detect: Monitor alerts, user reports
2. Triage: Determine severity and impact
3. Contain: Isolate affected systems
4. Eradicate: Remove root cause
5. Recover: Restore normal operations
6. Learn: Post-mortem and process improvement
Summary
A mature Secure SDLC integrates security activities into every phase of development. Start with threat modeling during design, enforce secure coding standards during implementation, automate SAST and dependency scanning in CI/CD, perform DAST before deployment, and maintain a vulnerability management program for production. The earlier a vulnerability is found, the cheaper and easier it is to fix.