Search…
DevSecOps · Part 2

Shift-left security

In this series (10 parts)
  1. What DevSecOps means
  2. Shift-left security
  3. SAST and DAST
  4. Software supply chain security
  5. Container security
  6. Kubernetes security in depth
  7. Secrets management in practice
  8. Cloud security posture management
  9. Compliance as code
  10. Incident response for DevSecOps

The cheapest vulnerability is one that never reaches a repository. Shift-left security moves detection to the developer’s machine, catching secrets, insecure patterns, and design flaws before they enter version control.

Pre-commit secret scanning

Leaked secrets are the most common and most damaging security failure in modern development. API keys, database passwords, and private certificates pushed to a repository become permanent fixtures of Git history. Even after deletion, they remain accessible through git log.

gitleaks

gitleaks scans commits for patterns matching known secret formats. Install it and configure a pre-commit hook:

brew install gitleaks

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks

Run it manually against your repository history:

gitleaks detect --source . --verbose

gitleaks ships with rules for AWS keys, GitHub tokens, Slack webhooks, and hundreds more. Custom rules use regular expressions:

# .gitleaks.toml
[[rules]]
id = "internal-api-key"
description = "Internal API key pattern"
regex = '''INTERNAL_KEY_[A-Z0-9]{32}'''
tags = ["internal", "api-key"]

git-secrets

AWS provides git-secrets specifically for catching AWS credential patterns:

git secrets --install
git secrets --register-aws

# Scan all commits
git secrets --scan-history

TruffleHog

TruffleHog takes a different approach. Instead of pattern matching alone, it calculates entropy of strings. High-entropy strings that look like random data are flagged as potential secrets:

trufflehog git file://. --only-verified

The --only-verified flag reduces false positives by actually testing whether discovered credentials are valid. This is powerful but should only run in controlled environments.

Security linting

Linters catch insecure code patterns before they become vulnerabilities. Unlike SAST tools that analyze entire applications, security linters operate on individual files with fast feedback loops.

ESLint security plugin for JavaScript:

npm install --save-dev eslint-plugin-security
{
  "plugins": ["security"],
  "extends": ["plugin:security/recommended"]
}

This catches patterns like eval() usage, non-literal require(), and unsafe regular expressions vulnerable to ReDoS attacks.

Bandit for Python:

pip install bandit
bandit -r src/ -f json -o bandit-report.json

Bandit flags hardcoded passwords, use of subprocess with shell=True, insecure hash algorithms like MD5 and SHA1, and XML parsing without defenses against XXE attacks.

gosec for Go:

go install github.com/securego/gosec/v2/cmd/gosec@latest
gosec ./...

gosec detects SQL injection through string concatenation, weak random number generation with math/rand, and unhandled errors on security-critical operations.

Developer security training

Tools catch known patterns. Training builds the judgment to recognize novel threats. Effective security training has three properties: it is continuous, practical, and integrated into daily work.

Code review checklists. Add security-specific items to your review template:

  • Are inputs validated and sanitized?
  • Are errors handled without leaking internal details?
  • Are authentication and authorization checks present?
  • Are sensitive operations logged for audit?

Capture-the-flag exercises. Platforms like OWASP WebGoat, Hack The Box, and PentesterLab provide hands-on practice with real vulnerabilities in safe environments. Monthly team CTF sessions build skills and create shared vocabulary.

Security office hours. Designate a weekly time when security engineers are available for architecture discussions, code review questions, and threat modeling sessions. Low-friction access to expertise prevents developers from guessing.

Threat modeling with STRIDE

STRIDE is a structured approach to identifying threats during system design. It categorizes threats into six types:

CategoryThreatExample
SpoofingPretending to be someone elseForged authentication tokens
TamperingModifying data or codeMan-in-the-middle attack on API calls
RepudiationDenying actionsUser disputes a transaction with no audit log
Information DisclosureExposing confidential dataError messages revealing stack traces
Denial of ServiceMaking a system unavailableUnbounded query consuming all memory
Elevation of PrivilegeGaining unauthorized accessSQL injection escalating to admin

Running a threat modeling session

Threat modeling works best with 3-5 participants: developers, a security champion, and an architect. Follow this process:

  1. Draw the system. Create a data flow diagram showing components, trust boundaries, and data flows.
  2. Apply STRIDE to each element. For each component and data flow, ask: “How could each STRIDE category apply here?”
  3. Prioritize. Use risk = likelihood x impact to rank threats.
  4. Mitigate. For each high-priority threat, define a countermeasure and assign an owner.
graph TB
  subgraph Trust Boundary: Internet
      U[User Browser]
  end
  subgraph Trust Boundary: DMZ
      LB[Load Balancer]
      WAF[Web Application Firewall]
  end
  subgraph Trust Boundary: Internal
      API[API Server]
      DB[(Database)]
      Cache[(Redis Cache)]
  end

  U -->|HTTPS| WAF
  WAF --> LB
  LB --> API
  API --> DB
  API --> Cache

  style U fill:#ffeaa7
  style WAF fill:#74b9ff
  style LB fill:#74b9ff
  style API fill:#55efc4
  style DB fill:#fd79a8
  style Cache fill:#fd79a8

Data flow diagram with trust boundaries. Each arrow crossing a boundary is a potential attack surface requiring STRIDE analysis.

Documenting threat models

Store threat models alongside code in version control. A simple markdown template works:

# Threat Model: Payment Service

## Assets
- Customer payment data (PCI scope)
- Merchant credentials

## Threats
| ID | STRIDE | Component | Threat | Mitigation | Owner |
|----|--------|-----------|--------|------------|-------|
| T1 | Spoofing | API Gateway | Forged JWT tokens | Validate signatures with public key rotation | @auth-team |
| T2 | Tampering | Payment API | Modified transaction amounts | Sign requests with HMAC | @payments |
| T3 | Info Disclosure | Error handler | Stack traces in responses | Custom error handler, strip details in prod | @api-team |

## Review Schedule
- Quarterly review or on major architecture changes

This creates an auditable record of security decisions. When architecture changes, the threat model guides which new threats to evaluate.

Measuring shift-left effectiveness

Track these metrics to evaluate your shift-left program:

  • Pre-commit block rate: percentage of commits blocked by local hooks. A high rate initially is healthy; it should decrease as developers internalize patterns.
  • Mean time to fix: how quickly developers resolve findings from local tools vs CI tools vs production scanners.
  • Escaped defects: security issues found in later stages that shift-left tooling should have caught. Each escape is an opportunity to add a new rule.

As shift-left matures, the ratio of findings caught early vs late should increase steadily.

What comes next

The next article on SAST and DAST covers the automated scanning tools that run during build and test phases. You will learn how to integrate Semgrep and OWASP ZAP into CI pipelines and manage the false positives that inevitably arise.

Start typing to search across all content
navigate Enter open Esc close