Shift-Left Security with AI Assistance

Module 08: Security & Code Quality | Expansion Guide

Back to Module 08

The Problem

You finish a feature. Code review passes. QA approves. Then security team finds three critical vulnerabilities. Now you're rewriting authentication logic on Friday at 6pm because fixing security was left to the end.

The traditional approach: Security is a gate at the end. You build, then check for vulnerabilities.

This is backwards. By the time security reviews your code, you've already made architectural decisions. Ripping out insecure patterns means rewriting features, not tweaking them.

The Core Insight

Shift security left: Find vulnerabilities while coding, not after deployment.

The earlier you catch security issues, the cheaper they are to fix. A vulnerability caught during coding costs 1x. During code review: 10x. In production: 100x. Plus reputation damage, regulatory fines, incident response.

AI is uniquely positioned to help: it can review code for security issues in real-time as you write. You don't need a security expert on call - you have AI.

The Shift-Left Workflow

Layer 1: Pre-Coding Security

Before writing code, ask AI about security implications.

Prompt: "I'm building a user authentication system with JWT tokens.
What are the top 5 security considerations I should handle upfront?"

AI Response:
1. Store JWT secret in environment variables, not code
2. Set token expiration (24h recommended)
3. Use HTTP-only cookies, not localStorage (XSS prevention)
4. Implement refresh token rotation
5. Add rate limiting to login endpoint

Why this works: You design security in, not bolt it on later.

Layer 2: During Coding (Real-Time Review)

As AI generates code, immediately ask for security review.

Workflow:
1. Ask AI to generate feature
2. AI provides code
3. Before accepting: "Review this code for security vulnerabilities"
4. AI points out issues
5. Fix issues in same session
6. Accept hardened code

Time added: 2-3 minutes per feature
Vulnerabilities prevented: 80%+

The Security Sandwich Pattern

Generate → Review → Fix → Accept. Never skip the review layer. This becomes muscle memory after 10 iterations.

Layer 3: Post-Coding (Automated Scanning)

Run automated security tools before committing.

# Pre-commit security checks
npm audit              # Dependency vulnerabilities
eslint --ext .js,.jsx  # Code quality + security rules
semgrep --config=auto  # SAST scanning
git-secrets --scan     # Secret detection

# Set up as pre-commit hook
# .git/hooks/pre-commit
#!/bin/sh
npm audit --audit-level=high || exit 1
npm run lint:security || exit 1

AI Security Review Prompts

Prompt 1: General Security Audit

"Perform a security audit of this code. Check for:
1. Input validation gaps
2. SQL/NoSQL injection risks
3. XSS vulnerabilities
4. Authentication/authorization issues
5. Secrets hardcoded in source
6. Timing attacks
7. Resource exhaustion (DoS)
8. Insecure dependencies

Provide severity (Critical/High/Medium/Low) for each finding."

Prompt 2: OWASP Top 10 Review

"Review this code against OWASP Top 10 2021:
A01 Broken Access Control
A02 Cryptographic Failures
A03 Injection
A04 Insecure Design
A05 Security Misconfiguration
A06 Vulnerable Components
A07 Identification and Authentication Failures
A08 Software and Data Integrity Failures
A09 Security Logging Failures
A10 Server-Side Request Forgery

List any violations found."

Prompt 3: Threat Modeling

"Given this authentication endpoint:
[paste code]

Perform threat modeling:
1. What are possible attack vectors?
2. What happens if an attacker controls each input?
3. What are the trust boundaries?
4. What can go wrong with race conditions?
5. How could an attacker bypass this?

Think like a penetration tester."

Prompt 4: Language-Specific Security

# Python-specific
"Review this Python code for:
- Pickle deserialization vulnerabilities
- SQL injection via f-strings
- Command injection via os.system()
- Path traversal in file operations
- Timing attacks in comparisons"

# JavaScript-specific
"Review this Node.js code for:
- Prototype pollution
- ReDoS in regex
- XSS via innerHTML
- JWT secret exposure
- NoSQL injection in MongoDB queries"

The Walkthrough: Secure Feature Development

Task: Add password reset functionality.

Phase 1: Design Review (Before Coding)

Prompt: "I need to implement password reset via email.
What security measures are essential?"

AI Response:
1. Generate cryptographically random tokens (32+ bytes)
2. Hash tokens before storing in database
3. Set token expiration (15-30 minutes)
4. Invalidate token after single use
5. Rate limit reset requests (prevent email bombing)
6. Don't reveal if email exists (timing attack prevention)
7. Log all reset attempts (security monitoring)

Great, now I know what to build.

Phase 2: Implementation with Real-Time Review

Prompt: "Generate password reset endpoint following those security requirements"

AI generates code...

Prompt: "Review this for vulnerabilities before I accept it"

AI: "Found 2 issues:
1. Token is not cryptographically random (using Math.random)
2. No rate limiting implemented
Fix these before shipping."

I fix issues, re-review, then accept.

Phase 3: Automated Pre-Commit Checks

$ git add .
$ git commit -m "Add password reset"

# Pre-commit hook runs:
Running security checks...
✓ No secrets found
✓ No high-severity npm vulnerabilities
✓ ESLint security rules pass
✓ Semgrep found 0 issues

[main abc1234] Add password reset

Result: Secure feature shipped in first iteration. No security team escalation needed.

Automated Security Workflows

Setup 1: Pre-Commit Hooks

# Install husky for git hooks
npm install --save-dev husky

# Setup pre-commit
npx husky add .husky/pre-commit "npm run security-check"

# In package.json:
{
  "scripts": {
    "security-check": "npm audit && eslint . --ext .js --config .eslintrc.security.js"
  }
}

Setup 2: CI/CD Security Gates

# .github/workflows/security.yml
name: Security Scan
on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run Snyk
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
      - name: Run Semgrep
        uses: returntocorp/semgrep-action@v1
      - name: Check secrets
        uses: trufflesecurity/trufflehog@main

Setup 3: IDE Integration

# VS Code: Install extensions
- SonarLint (real-time security feedback)
- Snyk (dependency scanning)
- GitLens (see who wrote vulnerable code)

# Configure real-time security linting
# .vscode/settings.json
{
  "sonarlint.rules": {
    "javascript:S3330": { "level": "on" },  // Detect cipher weaknesses
    "javascript:S2068": { "level": "on" },  // Hard-coded credentials
    "javascript:S2092": { "level": "on" }   // Insecure cookie
  }
}

Don't Trust AI Blindly

AI can miss vulnerabilities. Always combine AI review with automated tools (Snyk, Semgrep, npm audit). Use AI as first pass, tools as verification.

Failure Patterns

1. Security Review After Feature Complete

Symptom: You build entire feature, then discover fundamental security issues.

Fix: Review security during design phase, not after coding.

2. Only Automated Scanning

Symptom: Tools pass, but logic flaws exist (business logic bypasses).

Fix: Combine automated tools with AI threat modeling prompts.

3. Ignoring Low Severity Issues

Symptom: "It's just low severity, we'll fix later." Never gets fixed.

Fix: Fix ALL issues before merging. Low severity stacks up.

Measuring Shift-Left Success

Metrics to track:

Stage Cost to Fix Shift-Left Impact
During coding 1x (minutes) ✓ Main target
Code review 10x (hours) ✓ Backup catch
QA testing 50x (days) Rare if shift-left works
Production 100x+ (weeks) Should never happen

Quick Reference

Shift-Left Security Checklist:

[ ] Before Coding:

[ ] During Coding:

[ ] Before Committing:

[ ] In CI/CD:

Quick AI Security Prompt:

"Security review this code for:
- Input validation
- SQL/XSS injection
- Auth bypasses
- Hardcoded secrets
- DoS vulnerabilities

Be critical. What could an attacker exploit?"

Tools to Install Today: