Finding and fixing a security vulnerability in production costs 100 times more than catching it during design. Yet most organizations still treat security as a final checkpoint—something to verify after development is complete, rather than a fundamental part of how software is built.
Over 70% of successful attacks exploit vulnerabilities introduced during the software development lifecycle (SDLC). SQL injection, cross-site scripting, authentication flaws, insecure configurations—these issues aren't inevitable. They're the result of development processes that don't account for security until it's expensive and disruptive to fix.
This guide covers how to integrate security into every SDLC phase, from requirements gathering through deployment and maintenance. Whether you're implementing DevSecOps for the first time or maturing existing practices, these principles and tools will help you build security in rather than bolt it on.
SDLC Phases Overview
The software development lifecycle provides a framework for building software systematically. While methodologies vary (Waterfall, Agile, DevOps), the fundamental phases remain consistent:
Traditional SDLC Phases
- Planning/Requirements: Define what to build and why
- Design: Architect the solution
- Development: Write the code
- Testing: Verify functionality and quality
- Deployment: Release to production
- Maintenance: Operate and improve
Where Security Fits
Traditional approaches add security late in the process—penetration testing before release, security reviews after development. This creates several problems:
- Late discovery: Issues found late are expensive to fix
- Schedule pressure: Security becomes a blocker rather than enabler
- Friction: Developers see security as an obstacle
- Incomplete coverage: Time constraints mean shortcuts
Shift-left security moves security activities earlier in the lifecycle:
| Phase | Traditional Security | Shift-Left Security |
|---|---|---|
| Planning | Minimal | Security requirements, risk assessment |
| Design | None | Threat modeling, secure architecture |
| Development | None | Secure coding, code review, SAST |
| Testing | Penetration testing | SAST, DAST, IAST, security regression |
| Deployment | Manual review | Automated gates, infrastructure scanning |
| Maintenance | Incident response | Continuous monitoring, vulnerability management |
Security in the Planning Phase
Security begins before any code is written.
Security Requirements Gathering
Capture security needs alongside functional requirements:
Authentication requirements:
- Who needs access?
- What authentication methods are appropriate?
- What session management is needed?
Authorization requirements:
- What access control model (RBAC, ABAC)?
- What are the permission levels?
- How granular does access control need to be?
Data protection requirements:
- What data is sensitive?
- What encryption is needed (transit, rest)?
- What are data retention requirements?
Compliance requirements:
- What regulations apply (GDPR, HIPAA, PCI-DSS)?
- What security controls are mandated?
- What audit/logging requirements exist?
Risk Assessment
Evaluate security risk early:
- Asset identification: What are you protecting?
- Threat identification: Who might attack and how?
- Vulnerability assessment: What weaknesses exist?
- Impact analysis: What's the potential damage?
- Risk rating: Prioritize based on likelihood × impact
Risk-based prioritization: Not all features need the same security investment. A public marketing page needs less scrutiny than a payment processing module.
Security User Stories
Express security requirements in Agile terms:
As a user, I want my session to expire after 30 minutes of inactivity
so that my account is protected if I forget to log out.
As an administrator, I want to see audit logs of all data exports
so that I can investigate potential data breaches.
As a developer, I want automated dependency scanning in CI
so that I'm alerted to vulnerable libraries before they reach production.
Acceptance criteria should include security verification:
Given: A user is authenticated
When: They are inactive for 30 minutes
Then: They are automatically logged out
And: Their session token is invalidated
And: They must re-authenticate to continue
Security in the Design Phase
Architecture decisions made during design have the biggest impact on security.
Threat Modeling
Systematically identify threats to your application:
STRIDE methodology:
| Threat | Description | Example |
|---|---|---|
| Spoofing | Impersonating something or someone | Forged authentication |
| Tampering | Modifying data or code | SQL injection |
| Repudiation | Denying actions | Missing audit logs |
| Information disclosure | Exposing information | Data leak |
| Denial of service | Making system unavailable | Resource exhaustion |
| Elevation of privilege | Gaining unauthorized access | Privilege escalation |
Threat modeling process:
- Diagram the system: Data flow diagrams showing components, data stores, trust boundaries
- Identify threats: Use STRIDE against each element
- Document threats: Describe attack scenarios
- Rate threats: DREAD scoring or similar
- Plan mitigations: Controls to address each threat
- Track resolution: Ensure mitigations are implemented
Tools:
- Microsoft Threat Modeling Tool (free)
- OWASP Threat Dragon (open source)
- IriusRisk (commercial)
Secure Architecture Patterns
Design with security built in:
Defense in depth:
[Users] → [WAF] → [Load Balancer] → [App Servers] → [Internal Firewall] → [Database]
↓
[SIEM/Monitoring]
Multiple layers ensure single failures don't compromise everything.
Principle of least privilege:
- Services run with minimum necessary permissions
- Users get minimum access needed for their role
- Network segments are isolated by function
Secure defaults:
- Security features enabled by default
- Explicit opt-out rather than opt-in for security
- Conservative default configurations
Authentication and Authorization Design
Plan authentication architecture early:
Authentication options:
- Session-based (stateful, server stores session)
- Token-based JWT (stateless, client stores token)
- OAuth 2.0/OIDC (delegated authentication)
Authorization models:
- RBAC (Role-Based): Permissions assigned to roles, users assigned to roles
- ABAC (Attribute-Based): Permissions based on user/resource/environment attributes
- ReBAC (Relationship-Based): Permissions based on relationships (used by Google Zanzibar)
Data Flow Analysis
Map how sensitive data moves through your system:
- Where does data enter?
- Where is it stored?
- How is it processed?
- Where does it exit?
- Who can access it at each point?
Identify where encryption, access controls, and logging are needed.
Security in the Development Phase
Developers are your first line of defense.
Secure Coding Standards
Adopt recognized standards:
OWASP guidelines:
- OWASP Top 10: Most critical web application security risks
- OWASP ASVS: Application Security Verification Standard
- OWASP Cheat Sheets: Specific guidance by topic
Language-specific guidance:
- CERT Secure Coding Standards (C, C++, Java)
- PEP 8 + security extensions (Python)
- ESLint security plugins (JavaScript)
Common vulnerability prevention:
// SQL Injection - NEVER concatenate user input
// BAD
const query = `SELECT * FROM users WHERE id = ${userId}`;
// GOOD - Parameterized queries
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId]);
// XSS - ALWAYS encode output
// BAD
element.innerHTML = userInput;
// GOOD - Use text content or encode
element.textContent = userInput;
// OR
element.innerHTML = encodeHTML(userInput);
Code Review Practices
Security-focused code review checklist:
Authentication/Authorization:
- All endpoints require appropriate authentication
- Authorization checks prevent privilege escalation
- Session management is secure
Input validation:
- All user input is validated
- Validation happens server-side
- Error messages don't reveal sensitive info
Data protection:
- Sensitive data is encrypted
- Secrets aren't hardcoded
- Logs don't contain sensitive data
Common vulnerabilities:
- SQL injection prevented (parameterized queries)
- XSS prevented (output encoding)
- CSRF tokens implemented
- Directory traversal prevented
IDE Security Plugins
Catch issues as you code:
Visual Studio Code:
- Snyk Security
- SonarLint
- ESLint with security plugins
- Semgrep
JetBrains IDEs:
- SonarLint
- Snyk Security
- Find Security Bugs (Java)
Configuration example (ESLint):
{
"plugins": ["security"],
"extends": ["plugin:security/recommended"],
"rules": {
"security/detect-object-injection": "error",
"security/detect-non-literal-regexp": "warn",
"security/detect-unsafe-regex": "error",
"security/detect-buffer-noassert": "error",
"security/detect-eval-with-expression": "error"
}
}
Dependency Scanning (SCA)
Third-party components are a major attack surface:
Software Composition Analysis tools:
- Snyk: Comprehensive SCA with fix suggestions
- Dependabot: GitHub-native, automatic PRs
- OWASP Dependency-Check: Open source scanner
- WhiteSource: Enterprise-grade SCA
Integration example (GitHub Actions):
name: Security Scan
on: [push, pull_request]
jobs:
dependency-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Snyk
uses: snyk/actions/node@master
with:
args: --severity-threshold=high
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
Secrets Management
Never commit secrets to version control:
Pre-commit hooks:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
Secrets management solutions:
- HashiCorp Vault
- AWS Secrets Manager
- Azure Key Vault
- Google Secret Manager
- 1Password Secrets Automation
Environment variable pattern:
# Never in code
DATABASE_PASSWORD=secret123 # BAD
# In environment (not committed)
export DATABASE_PASSWORD=$(vault kv get -field=password secret/database)
Security in the Testing Phase
Multiple testing approaches catch different vulnerability classes.
Static Application Security Testing (SAST)
Analyze source code without execution:
Capabilities:
- Find code-level vulnerabilities (SQL injection, XSS, etc.)
- Identify dangerous function usage
- Detect hardcoded secrets
- Enforce coding standards
Limitations:
- High false positive rates
- Can't detect runtime issues
- Limited understanding of data flow across components
Popular SAST tools:
- SonarQube (open source + commercial)
- Checkmarx (commercial)
- Veracode (commercial)
- Semgrep (open source)
- CodeQL (GitHub Advanced Security)
CI/CD integration:
# GitHub Actions with CodeQL
name: CodeQL Analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v2
with:
languages: javascript
- uses: github/codeql-action/autobuild@v2
- uses: github/codeql-action/analyze@v2
Dynamic Application Security Testing (DAST)
Test running applications like an attacker would:
Capabilities:
- Find runtime vulnerabilities
- Test authentication/authorization
- Discover configuration issues
- No source code needed
Limitations:
- Requires running application
- Can't find all code paths
- Slower than SAST
- May miss vulnerabilities without proper coverage
Popular DAST tools:
- OWASP ZAP (open source)
- Burp Suite (commercial)
- Invicti (formerly Netsparker)
- Acunetix
- HCL AppScan
Basic OWASP ZAP automation:
# Run ZAP baseline scan
docker run -t owasp/zap2docker-stable zap-baseline.py \
-t https://your-app.com \
-r report.html
Interactive Application Security Testing (IAST)
Instrument running applications for deep visibility:
Capabilities:
- Combines SAST accuracy with DAST realism
- Lower false positives than SAST
- Identifies exact vulnerable code lines
- Works during functional testing
Limitations:
- Requires application instrumentation
- Language/framework specific
- Performance overhead
- More complex setup
Popular IAST tools:
- Contrast Security
- Checkmarx IAST
- Synopsys Seeker
- Veracode IAST
Penetration Testing
Expert-driven security testing:
Types:
- Black box: No knowledge of internals
- White box: Full access to code and architecture
- Gray box: Partial knowledge (most common)
When to conduct:
- Before major releases
- After significant changes
- Annually at minimum
- For compliance requirements
Scope definition:
- Target systems and URLs
- Test types allowed
- Timeline and rules of engagement
- Reporting requirements
Security Regression Testing
Ensure fixed vulnerabilities stay fixed:
// Example: Security regression test
describe('Authentication Security', () => {
it('should reject SQL injection in username', async () => {
const maliciousInput = "admin'; DROP TABLE users; --";
const response = await login(maliciousInput, 'password');
expect(response.status).toBe(400);
// Verify users table still exists
const users = await db.query('SELECT COUNT(*) FROM users');
expect(users.count).toBeGreaterThan(0);
});
it('should enforce rate limiting on login', async () => {
for (let i = 0; i < 10; i++) {
await login('test', 'wrong');
}
const response = await login('test', 'wrong');
expect(response.status).toBe(429);
});
});
Security in Deployment and Operations
Secure deployment extends security through release and runtime.
Secure CI/CD Pipelines
Protect the software supply chain:
Pipeline security controls:
# Example secure pipeline
name: Secure Deployment
on:
push:
branches: [main]
jobs:
security-checks:
runs-on: ubuntu-latest
steps:
# Verify commits are signed
- name: Verify signatures
run: git verify-commit HEAD
# Scan dependencies
- name: Dependency scan
uses: snyk/actions/node@master
# Static analysis
- name: SAST scan
uses: github/codeql-action/analyze@v2
# Container scanning
- name: Container scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
severity: 'CRITICAL,HIGH'
# Infrastructure as Code scan
- name: IaC scan
uses: bridgecrewio/checkov-action@master
deploy:
needs: security-checks
runs-on: ubuntu-latest
steps:
- name: Deploy to production
run: ./deploy.sh
Pipeline hardening:
- Require code review before merge
- Sign commits and artifacts
- Use immutable build environments
- Scan artifacts before deployment
- Implement deployment approvals
Container Security
Secure containerized deployments:
Image scanning:
# Scan image with Trivy
trivy image --severity HIGH,CRITICAL myapp:latest
Dockerfile security:
# Use specific, minimal base image
FROM node:20-alpine
# Run as non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# Don't expose unnecessary ports
EXPOSE 3000
# Use read-only filesystem where possible
# Set at runtime: docker run --read-only myapp
Kubernetes security:
# Pod security context
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Infrastructure as Code Security
Scan IaC before deployment:
Tools:
- Checkov (Terraform, CloudFormation, Kubernetes)
- tfsec (Terraform specific)
- KICS (multiple IaC formats)
- Terrascan
Example findings:
- S3 buckets without encryption
- Security groups allowing 0.0.0.0/0
- IAM policies with excessive permissions
- Unencrypted databases
Runtime Protection
Monitor applications in production:
Runtime Application Self-Protection (RASP):
- Instrument application at runtime
- Detect and block attacks in real-time
- Minimal false positives (has execution context)
Web Application Firewall (WAF):
- Block common attack patterns
- Virtual patching for known vulnerabilities
- Rate limiting and bot protection
Logging and monitoring:
- Security-relevant events to SIEM
- Real-time alerting on anomalies
- Audit trails for compliance
Frequently Asked Questions
1. What is a secure SDLC?
A secure SDLC integrates security activities into every phase of software development rather than treating security as a final checkpoint. This includes security requirements in planning, threat modeling in design, secure coding and SAST in development, security testing (DAST, penetration testing) before release, and ongoing monitoring in production. The goal is to find and fix vulnerabilities early when they're cheaper to address.
2. What is shift-left security?
Shift-left security means moving security activities earlier ("left") in the development timeline. Instead of penetration testing only before release, you add security requirements during planning, threat models during design, and automated security scanning during development. This catches vulnerabilities earlier when they're 10-100x cheaper to fix and prevents security from becoming a release blocker.
3. How do I integrate security into CI/CD?
Integrate security scanners as pipeline stages: dependency scanning (SCA) checks for vulnerable libraries, static analysis (SAST) scans code for vulnerabilities, container scanning checks images, and infrastructure-as-code scanning validates configurations. Configure pipelines to fail on critical findings, but tune thresholds to avoid blocking on false positives. Start with visibility (warnings) and gradually enforce (blocking).
4. What is the difference between SAST and DAST?
SAST (Static Application Security Testing) analyzes source code without running the application—it's fast, finds code-level issues early, but has high false positive rates and can't detect runtime issues. DAST (Dynamic Application Security Testing) tests running applications like an attacker would—it finds runtime issues with lower false positives but requires a deployed application and can't find all code paths. Use both for comprehensive coverage.
5. How often should security testing occur?
Security testing should be continuous, not periodic. SAST and dependency scanning should run on every commit or pull request. DAST can run daily or on staging deployments. Penetration testing by experts should occur at least annually and before major releases. The key is automating what you can so security testing doesn't become a bottleneck.
6. What is threat modeling?
Threat modeling is a structured approach to identifying security threats to your application. You diagram the system (data flows, trust boundaries), systematically identify threats using frameworks like STRIDE, document potential attack scenarios, and plan mitigations. It's most valuable during design when architectural changes are still feasible. Tools like Microsoft Threat Modeling Tool and OWASP Threat Dragon help structure the process.
7. What compliance frameworks require secure SDLC?
Many frameworks require or recommend secure development practices: PCI-DSS requires secure development training and code reviews; HIPAA requires security in system development; SOC 2 includes secure development criteria; ISO 27001 covers development security; NIST frameworks reference secure SDLC extensively. Even where not required, demonstrating secure development practices helps during audits.
8. How do I measure SDLC security maturity?
Use maturity models like OWASP SAMM (Software Assurance Maturity Model) or BSIMM (Building Security In Maturity Model). Key metrics include: vulnerability density over time, time to remediate findings, percentage of projects with threat models, SAST/DAST coverage, security training completion rates, and security debt backlog. Start by measuring where you are, set realistic goals, and track improvement.
9. What is DevSecOps?
DevSecOps integrates security into DevOps practices—security becomes everyone's responsibility, not just a security team's. It emphasizes automation (security scanning in CI/CD), collaboration (security engineers embedded with development teams), and shared ownership. The goal is security at DevOps speed: fast feedback, continuous improvement, and security that enables rather than blocks delivery.
10. What are the most common SDLC security mistakes?
Common mistakes include: treating security as a final gate rather than continuous practice; not training developers in secure coding; relying solely on penetration testing; ignoring third-party dependency risks; not doing threat modeling; having security tools but ignoring their output; making security someone else's problem rather than shared responsibility; and not measuring or tracking security metrics over time.
Conclusion
Integrating security into the SDLC isn't about adding more work—it's about doing security work at the right time. Catching a vulnerability during code review costs a fraction of finding it in production. Threat modeling during design prevents architectural flaws that would require major rewrites later.
Start where you are. If you're doing nothing, add dependency scanning and SAST to your CI pipeline—these provide immediate visibility with minimal friction. If you already have automated scanning, focus on developer training and threat modeling to prevent vulnerabilities rather than just detecting them.
The most mature organizations don't think of security as a separate activity. Security is how they build software—baked into requirements, architecture, code, testing, and deployment. Getting there is a journey, but every step makes your applications more secure and your security program more sustainable.
Related Tools
- JSON Formatter - Format and validate JSON for API security testing
- Regex Tester - Test regular expressions for input validation patterns