Security Scanning and Vulnerability Detection with AI

Security vulnerabilities cost organizations an average of $4.35 million per breach in 2023. Traditional security scanning catches obvious flaws but misses subtle vulnerabilities hidden in business logic, authentication flows, and complex dependency chains. AI-powered security tools are revolutionizing how we detect, prioritize, and remediate vulnerabilities, enabling true shift-left security that integrates seamlessly into development workflows.

In this comprehensive guide, we'll explore how to leverage AI-enhanced security tools like Snyk, Dependabot, and OWASP ZAP to build a robust security scanning pipeline. You'll learn practical techniques for identifying authentication flaws, detecting injection vulnerabilities, analyzing dependency risks, and generating security patches automatically.

The AI-Powered Security Landscape

Modern AI security tools go far beyond pattern matching. They understand code context, recognize vulnerability patterns across languages, and predict potential attack vectors. Here's what sets AI-powered security apart:

  • Contextual analysis - AI understands data flow and can trace tainted input through complex call chains
  • Reduced false positives - Machine learning models filter noise, reducing false positives by 60-80%
  • Intelligent prioritization - AI ranks vulnerabilities by actual exploitability, not just severity scores
  • Automated remediation - Generate fix suggestions that maintain functionality while closing security gaps
  • Continuous learning - Models improve from new vulnerability discoveries and attack patterns

Integrating Snyk for Comprehensive Vulnerability Scanning

Snyk provides AI-enhanced security scanning for source code, dependencies, containers, and infrastructure as code. Let's set up a comprehensive Snyk integration.

Initial Snyk Setup and Configuration

# Install Snyk CLI
npm install -g snyk

# Authenticate with Snyk
snyk auth

# Test your project for vulnerabilities
snyk test

# Monitor project for new vulnerabilities
snyk monitor

Create a comprehensive Snyk configuration file:

# .snyk - Snyk policy file
version: v1.25.0

# Ignore specific vulnerabilities with justification
ignore:
  SNYK-JS-LODASH-567746:
    - '*':
        reason: 'Low severity, no user input reaches affected function'
        expires: 2025-06-01T00:00:00.000Z

# Patch vulnerabilities where possible
patch:
  SNYK-JS-AXIOS-1038255:
    - axios:
        patched: '2025-01-15T10:30:00.000Z'

# Exclude test files from scanning
exclude:
  global:
    - '**/__tests__/**'
    - '**/*.test.ts'
    - '**/test/**'

Snyk CI/CD Pipeline Integration

Integrate Snyk into your GitHub Actions workflow for continuous security scanning:

# .github/workflows/security-scan.yml
name: Security Scanning Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  schedule:
    # Run daily at midnight
    - cron: '0 0 * * *'

env:
  SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

jobs:
  snyk-code:
    name: Snyk Code Analysis (SAST)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run Snyk Code test
        uses: snyk/actions/node@master
        continue-on-error: true
        with:
          command: code test
          args: --severity-threshold=high --sarif-file-output=snyk-code.sarif

      - name: Upload SARIF to GitHub
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: snyk-code.sarif

  snyk-deps:
    name: Dependency Vulnerability Scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run Snyk dependency test
        uses: snyk/actions/node@master
        with:
          command: test
          args: --severity-threshold=medium --json-file-output=snyk-deps.json

      - name: Parse and comment on PR
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const results = JSON.parse(fs.readFileSync('snyk-deps.json', 'utf8'));

            if (results.vulnerabilities && results.vulnerabilities.length > 0) {
              const vulnSummary = results.vulnerabilities
                .slice(0, 10)
                .map(v => `- **${v.severity}**: ${v.title} in \`${v.packageName}\``)
                .join('\n');

              await github.rest.issues.createComment({
                issue_number: context.issue.number,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body: `## Security Scan Results\n\n${vulnSummary}\n\n[View full report](${results.projectUrl})`
              });
            }

  snyk-container:
    name: Container Security Scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build Docker image
        run: docker build -t myapp:${{ github.sha }} .

      - name: Run Snyk container test
        uses: snyk/actions/docker@master
        with:
          image: myapp:${{ github.sha }}
          args: --severity-threshold=high

  snyk-iac:
    name: Infrastructure as Code Scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run Snyk IaC test
        uses: snyk/actions/iac@master
        with:
          args: --severity-threshold=medium

Configuring Dependabot for Automated Updates

Dependabot automatically creates pull requests to update vulnerable dependencies. Configure it for intelligent, security-focused updates:

# .github/dependabot.yml
version: 2
updates:
  # NPM dependencies
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "daily"
      time: "09:00"
      timezone: "America/New_York"
    open-pull-requests-limit: 10

    # Group security updates
    groups:
      security-patches:
        applies-to: security-updates
        patterns:
          - "*"
        update-types:
          - "patch"

      development-dependencies:
        patterns:
          - "@types/*"
          - "eslint*"
          - "prettier*"
          - "jest*"
          - "vitest*"
        update-types:
          - "minor"
          - "patch"

    # Ignore specific packages
    ignore:
      - dependency-name: "aws-sdk"
        update-types: ["version-update:semver-major"]

    # Customize commit messages
    commit-message:
      prefix: "deps"
      prefix-development: "deps-dev"
      include: "scope"

    # Labels for categorization
    labels:
      - "dependencies"
      - "security"

    # Reviewers for security updates
    reviewers:
      - "security-team"

    # Allow specific ecosystems
    allow:
      - dependency-type: "production"

  # Docker dependencies
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"
    labels:
      - "docker"
      - "infrastructure"

  # GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    labels:
      - "ci-cd"

Automating Dependabot PR Management

# .github/workflows/dependabot-automation.yml
name: Dependabot Automation

on:
  pull_request:
    types: [opened, synchronize]

permissions:
  contents: write
  pull-requests: write

jobs:
  auto-approve-merge:
    runs-on: ubuntu-latest
    if: github.actor == 'dependabot[bot]'
    steps:
      - name: Fetch Dependabot metadata
        id: dependabot-metadata
        uses: dependabot/fetch-metadata@v2
        with:
          github-token: "${{ secrets.GITHUB_TOKEN }}"

      - name: Auto-approve patch updates
        if: steps.dependabot-metadata.outputs.update-type == 'version-update:semver-patch'
        run: gh pr review --approve "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Auto-merge security patches
        if: steps.dependabot-metadata.outputs.update-type == 'version-update:semver-patch' &&
            contains(steps.dependabot-metadata.outputs.dependency-names, 'security')
        run: gh pr merge --auto --squash "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

SAST Implementation with AI Enhancement

Static Application Security Testing (SAST) analyzes source code for vulnerabilities without execution. Here's how to implement comprehensive SAST with AI enhancement:

// security/sast-config.ts
import { ESLint } from 'eslint';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

interface SecurityFinding {
  severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
  category: string;
  message: string;
  file: string;
  line: number;
  column: number;
  rule: string;
  cwe?: string;
  owasp?: string;
  remediation?: string;
}

export class SASTScanner {
  private findings: SecurityFinding[] = [];

  async runSecurityLinting(): Promise<SecurityFinding[]> {
    const eslint = new ESLint({
      overrideConfigFile: '.eslintrc.security.js',
      extensions: ['.js', '.ts', '.jsx', '.tsx']
    });

    const results = await eslint.lintFiles(['src/**/*']);

    for (const result of results) {
      for (const message of result.messages) {
        if (this.isSecurityRule(message.ruleId)) {
          this.findings.push({
            severity: this.mapSeverity(message.severity),
            category: this.categorizeRule(message.ruleId!),
            message: message.message,
            file: result.filePath,
            line: message.line,
            column: message.column,
            rule: message.ruleId || 'unknown',
            cwe: this.getCWE(message.ruleId),
            owasp: this.getOWASP(message.ruleId),
            remediation: this.getRemediation(message.ruleId)
          });
        }
      }
    }

    return this.findings;
  }

  private isSecurityRule(ruleId: string | null): boolean {
    if (!ruleId) return false;
    const securityPrefixes = [
      'security/',
      'no-secrets/',
      '@typescript-eslint/no-explicit-any',
      'no-eval',
      'no-implied-eval',
      'no-new-func'
    ];
    return securityPrefixes.some(prefix => ruleId.startsWith(prefix));
  }

  private mapSeverity(severity: number): SecurityFinding['severity'] {
    switch (severity) {
      case 2: return 'high';
      case 1: return 'medium';
      default: return 'low';
    }
  }

  private categorizeRule(ruleId: string): string {
    if (ruleId.includes('injection')) return 'Injection';
    if (ruleId.includes('xss')) return 'Cross-Site Scripting';
    if (ruleId.includes('auth')) return 'Authentication';
    if (ruleId.includes('crypto')) return 'Cryptography';
    if (ruleId.includes('secret')) return 'Secret Exposure';
    return 'General Security';
  }

  private getCWE(ruleId: string | null): string | undefined {
    const cweMapping: Record<string, string> = {
      'no-eval': 'CWE-95',
      'security/detect-sql-injection': 'CWE-89',
      'security/detect-xss': 'CWE-79',
      'security/detect-path-traversal': 'CWE-22',
      'security/detect-command-injection': 'CWE-78'
    };
    return ruleId ? cweMapping[ruleId] : undefined;
  }

  private getOWASP(ruleId: string | null): string | undefined {
    const owaspMapping: Record<string, string> = {
      'security/detect-sql-injection': 'A03:2021',
      'security/detect-xss': 'A03:2021',
      'security/detect-broken-auth': 'A07:2021',
      'security/detect-sensitive-data': 'A02:2021'
    };
    return ruleId ? owaspMapping[ruleId] : undefined;
  }

  private getRemediation(ruleId: string | null): string | undefined {
    const remediationGuide: Record<string, string> = {
      'no-eval': 'Replace eval() with JSON.parse() for data or use a sandboxed interpreter',
      'security/detect-sql-injection': 'Use parameterized queries or an ORM with proper escaping',
      'security/detect-xss': 'Sanitize user input with DOMPurify and use Content-Security-Policy headers'
    };
    return ruleId ? remediationGuide[ruleId] : undefined;
  }

  async generateReport(): Promise<string> {
    const findings = await this.runSecurityLinting();

    const summary = {
      total: findings.length,
      critical: findings.filter(f => f.severity === 'critical').length,
      high: findings.filter(f => f.severity === 'high').length,
      medium: findings.filter(f => f.severity === 'medium').length,
      low: findings.filter(f => f.severity === 'low').length
    };

    return JSON.stringify({ summary, findings }, null, 2);
  }
}

ESLint Security Configuration

// .eslintrc.security.js
module.exports = {
  plugins: [
    'security',
    'no-secrets',
    '@typescript-eslint'
  ],
  extends: [
    'plugin:security/recommended'
  ],
  rules: {
    // Injection Prevention
    'security/detect-object-injection': 'error',
    'security/detect-non-literal-regexp': 'warn',
    'security/detect-non-literal-require': 'error',
    'security/detect-non-literal-fs-filename': 'error',
    'security/detect-eval-with-expression': 'error',
    'security/detect-child-process': 'warn',

    // XSS Prevention
    'security/detect-possible-timing-attacks': 'warn',

    // Secret Detection
    'no-secrets/no-secrets': ['error', {
      tolerance: 4.5,
      additionalRegexes: {
        'AWS Key': /AKIA[0-9A-Z]{16}/,
        'Slack Token': /xox[baprs]-[0-9a-zA-Z]{10,}/,
        'GitHub Token': /ghp_[0-9a-zA-Z]{36}/,
        'Private Key': /-----BEGIN (RSA|EC|OPENSSH) PRIVATE KEY-----/
      }
    }],

    // Dangerous Functions
    'no-eval': 'error',
    'no-implied-eval': 'error',
    'no-new-func': 'error',

    // TypeScript Security
    '@typescript-eslint/no-explicit-any': 'warn',
    '@typescript-eslint/no-unsafe-assignment': 'warn',
    '@typescript-eslint/no-unsafe-call': 'warn',
    '@typescript-eslint/no-unsafe-member-access': 'warn'
  },
  overrides: [
    {
      files: ['**/*.test.ts', '**/*.spec.ts'],
      rules: {
        'security/detect-object-injection': 'off',
        'no-secrets/no-secrets': 'off'
      }
    }
  ]
};

DAST with OWASP ZAP

Dynamic Application Security Testing (DAST) tests running applications. Here's how to integrate OWASP ZAP for automated DAST:

# .github/workflows/dast-scan.yml
name: DAST Security Scan

on:
  deployment:
    types: [completed]

jobs:
  zap-scan:
    runs-on: ubuntu-latest
    if: github.event.deployment.environment == 'staging'

    steps:
      - uses: actions/checkout@v4

      - name: Wait for deployment
        run: |
          echo "Waiting for staging deployment to be ready..."
          sleep 60
          curl --retry 10 --retry-delay 10 --retry-connrefused \
            ${{ secrets.STAGING_URL }}/health

      - name: ZAP Baseline Scan
        uses: zaproxy/action-baseline@v0.10.0
        with:
          target: ${{ secrets.STAGING_URL }}
          rules_file_name: 'zap-rules.tsv'
          cmd_options: '-a -j -l WARN'

      - name: ZAP Full Scan
        uses: zaproxy/action-full-scan@v0.10.0
        with:
          target: ${{ secrets.STAGING_URL }}
          rules_file_name: 'zap-rules.tsv'
          cmd_options: '-a -j'

      - name: Upload ZAP Report
        uses: actions/upload-artifact@v4
        with:
          name: zap-report
          path: report_html.html

      - name: Parse ZAP results
        id: zap-results
        run: |
          HIGH_ALERTS=$(grep -c "High" report_html.html || echo 0)
          MEDIUM_ALERTS=$(grep -c "Medium" report_html.html || echo 0)
          echo "high_count=$HIGH_ALERTS" >> $GITHUB_OUTPUT
          echo "medium_count=$MEDIUM_ALERTS" >> $GITHUB_OUTPUT

      - name: Fail on critical findings
        if: steps.zap-results.outputs.high_count > 0
        run: |
          echo "Found ${{ steps.zap-results.outputs.high_count }} high severity vulnerabilities!"
          exit 1

ZAP Custom Rules Configuration

# zap-rules.tsv - Custom ZAP scan rules
# Rule ID	Rule Name	Threshold	Action
10016	Web Browser XSS Protection Not Enabled	MEDIUM	WARN
10017	Cross-Domain JavaScript Source File Inclusion	LOW	IGNORE
10019	Content-Type Header Missing	MEDIUM	WARN
10020	X-Frame-Options Header Not Set	HIGH	FAIL
10021	X-Content-Type-Options Header Missing	MEDIUM	WARN
10023	Information Disclosure - Debug Error Messages	HIGH	FAIL
10024	Information Disclosure - Sensitive Information in URL	HIGH	FAIL
10025	Information Disclosure - Sensitive Information in HTTP Referrer Header	MEDIUM	WARN
10027	Information Disclosure - Suspicious Comments	LOW	IGNORE
10028	Open Redirect	HIGH	FAIL
10029	Cookie Poisoning	HIGH	FAIL
10030	User Controllable Charset	MEDIUM	WARN
10031	User Controllable HTML Element Attribute	MEDIUM	WARN
10032	Viewstate	LOW	IGNORE
10035	Strict-Transport-Security Header Not Set	HIGH	FAIL
10036	Server Leaks Version Information via "Server" HTTP Response Header Field	LOW	WARN
10037	Server Leaks Information via "X-Powered-By" HTTP Response Header Field	LOW	WARN
10038	Content Security Policy (CSP) Header Not Set	MEDIUM	WARN
10039	X-Backend-Server Header Information Leak	MEDIUM	WARN
10040	Secure Pages Include Mixed Content	MEDIUM	WARN
10054	Cookie Without SameSite Attribute	MEDIUM	WARN
10055	CSP: Wildcard Directive	MEDIUM	WARN
10056	CSP: script-src unsafe-inline	HIGH	FAIL
10057	CSP: style-src unsafe-inline	MEDIUM	WARN
10061	X-AspNet-Version Response Header	LOW	WARN
10062	PII Disclosure	HIGH	FAIL
10096	Timestamp Disclosure	LOW	IGNORE
10097	Hash Disclosure	MEDIUM	WARN
10098	Cross-Domain Misconfiguration	MEDIUM	WARN
10105	Weak Authentication Method	HIGH	FAIL
10108	Reverse Tabnabbing	MEDIUM	WARN
10109	Modern Web Application	LOW	IGNORE
10110	Dangerous JS Functions	MEDIUM	WARN

AI-Generated Security Patches

Leverage AI to generate security patches for identified vulnerabilities:

// security/patch-generator.ts
import Anthropic from '@anthropic-ai/sdk';

interface Vulnerability {
  type: string;
  file: string;
  line: number;
  code: string;
  cwe: string;
  description: string;
}

interface SecurityPatch {
  originalCode: string;
  patchedCode: string;
  explanation: string;
  testCases: string[];
}

export class AISecurityPatchGenerator {
  private client: Anthropic;

  constructor() {
    this.client = new Anthropic();
  }

  async generatePatch(vulnerability: Vulnerability): Promise<SecurityPatch> {
    const prompt = `You are a security expert. Analyze this vulnerability and provide a secure fix.

Vulnerability Type: ${vulnerability.type}
CWE: ${vulnerability.cwe}
File: ${vulnerability.file}
Line: ${vulnerability.line}

Vulnerable Code:
\`\`\`
${vulnerability.code}
\`\`\`

Description: ${vulnerability.description}

Provide:
1. Patched code that fixes the vulnerability
2. Explanation of the fix
3. Test cases to verify the fix works

Respond in JSON format:
{
  "patchedCode": "...",
  "explanation": "...",
  "testCases": ["...", "..."]
}`;

    const response = await this.client.messages.create({
      model: 'claude-sonnet-4-20250514',
      max_tokens: 2000,
      messages: [{ role: 'user', content: prompt }]
    });

    const content = response.content[0];
    if (content.type !== 'text') {
      throw new Error('Unexpected response type');
    }

    const result = JSON.parse(content.text);

    return {
      originalCode: vulnerability.code,
      patchedCode: result.patchedCode,
      explanation: result.explanation,
      testCases: result.testCases
    };
  }

  async batchGeneratePatches(
    vulnerabilities: Vulnerability[]
  ): Promise<Map<string, SecurityPatch>> {
    const patches = new Map<string, SecurityPatch>();

    for (const vuln of vulnerabilities) {
      try {
        const patch = await this.generatePatch(vuln);
        patches.set(`${vuln.file}:${vuln.line}`, patch);
      } catch (error) {
        console.error(`Failed to generate patch for ${vuln.file}:${vuln.line}`, error);
      }
    }

    return patches;
  }
}

// Example usage
const generator = new AISecurityPatchGenerator();

const sqlInjectionVuln: Vulnerability = {
  type: 'SQL Injection',
  file: 'src/api/users.ts',
  line: 45,
  cwe: 'CWE-89',
  code: `
async function getUser(userId: string) {
  const query = \`SELECT * FROM users WHERE id = '\${userId}'\`;
  return await db.query(query);
}
  `,
  description: 'User input is directly concatenated into SQL query'
};

const patch = await generator.generatePatch(sqlInjectionVuln);
console.log('Patched code:', patch.patchedCode);
console.log('Explanation:', patch.explanation);

Intelligent Dependency Scanning

Go beyond basic dependency checking with intelligent vulnerability correlation:

// security/dependency-analyzer.ts
import { execSync } from 'child_process';

interface DependencyVulnerability {
  package: string;
  version: string;
  vulnerability: {
    id: string;
    severity: 'critical' | 'high' | 'medium' | 'low';
    title: string;
    description: string;
    exploitMaturity: 'proof-of-concept' | 'functional' | 'high' | 'no-known-exploit';
    isUpgradable: boolean;
    isPatchable: boolean;
    fixedIn: string | null;
  };
  paths: string[][];
  reachability: 'reachable' | 'potentially-reachable' | 'not-reachable' | 'unknown';
}

export class DependencySecurityAnalyzer {
  async scanDependencies(): Promise<DependencyVulnerability[]> {
    // Run npm audit with JSON output
    const auditOutput = execSync('npm audit --json', {
      encoding: 'utf-8',
      stdio: ['pipe', 'pipe', 'pipe']
    });

    const auditData = JSON.parse(auditOutput);
    return this.parseAuditResults(auditData);
  }

  async analyzeReachability(
    vulnerability: DependencyVulnerability
  ): Promise<'reachable' | 'not-reachable' | 'unknown'> {
    // Check if vulnerable function is actually called in codebase
    const vulnerableFunctions = await this.getVulnerableFunctions(
      vulnerability.vulnerability.id
    );

    for (const func of vulnerableFunctions) {
      const isUsed = await this.checkFunctionUsage(
        vulnerability.package,
        func
      );
      if (isUsed) return 'reachable';
    }

    return 'not-reachable';
  }

  private async getVulnerableFunctions(vulnId: string): Promise<string[]> {
    // Query vulnerability database for affected functions
    // This would integrate with Snyk or NVD API
    return [];
  }

  private async checkFunctionUsage(
    packageName: string,
    functionName: string
  ): Promise<boolean> {
    try {
      const grepResult = execSync(
        `grep -r "import.*${functionName}.*from.*${packageName}" src/ || true`,
        { encoding: 'utf-8' }
      );
      return grepResult.trim().length > 0;
    } catch {
      return false;
    }
  }

  private parseAuditResults(auditData: any): DependencyVulnerability[] {
    const vulnerabilities: DependencyVulnerability[] = [];

    for (const [name, advisory] of Object.entries(auditData.vulnerabilities || {})) {
      const adv = advisory as any;
      vulnerabilities.push({
        package: name,
        version: adv.range,
        vulnerability: {
          id: adv.via[0]?.source || 'unknown',
          severity: adv.severity,
          title: adv.via[0]?.title || 'Unknown vulnerability',
          description: adv.via[0]?.url || '',
          exploitMaturity: 'unknown' as any,
          isUpgradable: adv.fixAvailable !== false,
          isPatchable: false,
          fixedIn: adv.fixAvailable?.version || null
        },
        paths: adv.nodes || [],
        reachability: 'unknown'
      });
    }

    return vulnerabilities;
  }

  generateRemediationPlan(
    vulnerabilities: DependencyVulnerability[]
  ): string {
    const critical = vulnerabilities.filter(v => v.vulnerability.severity === 'critical');
    const high = vulnerabilities.filter(v => v.vulnerability.severity === 'high');

    let plan = '# Security Remediation Plan\n\n';

    plan += '## Immediate Actions (Critical)\n\n';
    for (const vuln of critical) {
      plan += `### ${vuln.package}@${vuln.version}\n`;
      plan += `- **Issue**: ${vuln.vulnerability.title}\n`;
      plan += `- **Fix**: ${vuln.vulnerability.fixedIn ? `Upgrade to ${vuln.vulnerability.fixedIn}` : 'No fix available'}\n`;
      plan += `- **Command**: \`npm update ${vuln.package}\`\n\n`;
    }

    plan += '## High Priority\n\n';
    for (const vuln of high) {
      plan += `### ${vuln.package}@${vuln.version}\n`;
      plan += `- **Issue**: ${vuln.vulnerability.title}\n`;
      plan += `- **Reachability**: ${vuln.reachability}\n`;
      plan += `- **Fix**: ${vuln.vulnerability.fixedIn ? `Upgrade to ${vuln.vulnerability.fixedIn}` : 'Consider alternative package'}\n\n`;
    }

    return plan;
  }
}

Authentication and Authorization Scanning

Detect common authentication flaws with specialized scanning:

// security/auth-scanner.ts
import { parse } from '@babel/parser';
import traverse from '@babel/traverse';
import * as fs from 'fs';
import * as glob from 'glob';

interface AuthVulnerability {
  type: 'broken-auth' | 'broken-access-control' | 'session-management' | 'credential-exposure';
  severity: 'critical' | 'high' | 'medium' | 'low';
  file: string;
  line: number;
  description: string;
  recommendation: string;
}

export class AuthenticationScanner {
  private vulnerabilities: AuthVulnerability[] = [];

  async scanProject(srcPath: string): Promise<AuthVulnerability[]> {
    const files = glob.sync(`${srcPath}/**/*.{ts,js,tsx,jsx}`);

    for (const file of files) {
      await this.scanFile(file);
    }

    return this.vulnerabilities;
  }

  private async scanFile(filePath: string): Promise<void> {
    const code = fs.readFileSync(filePath, 'utf-8');

    try {
      const ast = parse(code, {
        sourceType: 'module',
        plugins: ['typescript', 'jsx']
      });

      traverse(ast, {
        // Detect hardcoded credentials
        VariableDeclarator: (path) => {
          const init = path.node.init;
          if (init?.type === 'StringLiteral') {
            const value = init.value.toLowerCase();
            const name = path.node.id.type === 'Identifier'
              ? path.node.id.name.toLowerCase()
              : '';

            if (
              (name.includes('password') || name.includes('secret') || name.includes('key')) &&
              value.length > 5 &&
              !value.includes('${')
            ) {
              this.vulnerabilities.push({
                type: 'credential-exposure',
                severity: 'critical',
                file: filePath,
                line: path.node.loc?.start.line || 0,
                description: 'Hardcoded credential detected',
                recommendation: 'Use environment variables or a secrets manager'
              });
            }
          }
        },

        // Detect weak JWT configurations
        CallExpression: (path) => {
          const callee = path.node.callee;
          if (
            callee.type === 'MemberExpression' &&
            callee.property.type === 'Identifier' &&
            callee.property.name === 'sign'
          ) {
            const args = path.node.arguments;
            if (args.length >= 3) {
              const options = args[2];
              if (options.type === 'ObjectExpression') {
                const hasExpiry = options.properties.some(
                  p => p.type === 'ObjectProperty' &&
                       p.key.type === 'Identifier' &&
                       p.key.name === 'expiresIn'
                );

                if (!hasExpiry) {
                  this.vulnerabilities.push({
                    type: 'session-management',
                    severity: 'high',
                    file: filePath,
                    line: path.node.loc?.start.line || 0,
                    description: 'JWT token without expiration',
                    recommendation: 'Add expiresIn option to jwt.sign()'
                  });
                }
              }
            }
          }

          // Detect missing CSRF protection
          if (
            callee.type === 'Identifier' &&
            (callee.name === 'post' || callee.name === 'put' || callee.name === 'delete')
          ) {
            // Check for CSRF middleware in the handler chain
            // This is a simplified check
            const middlewares = path.node.arguments.slice(1, -1);
            const hasCsrf = middlewares.some(m => {
              if (m.type === 'Identifier') {
                return m.name.toLowerCase().includes('csrf');
              }
              return false;
            });

            if (!hasCsrf && path.node.arguments.length > 1) {
              this.vulnerabilities.push({
                type: 'broken-access-control',
                severity: 'medium',
                file: filePath,
                line: path.node.loc?.start.line || 0,
                description: 'State-changing endpoint may lack CSRF protection',
                recommendation: 'Add CSRF middleware to POST/PUT/DELETE routes'
              });
            }
          }
        }
      });
    } catch (error) {
      console.warn(`Failed to parse ${filePath}:`, error);
    }
  }
}

Security Improvement Metrics

Track and measure your security posture over time:

// security/metrics-collector.ts
interface SecurityMetrics {
  timestamp: Date;
  vulnerabilities: {
    total: number;
    critical: number;
    high: number;
    medium: number;
    low: number;
  };
  coverage: {
    sastCoverage: number;
    dastCoverage: number;
    dependencyScanning: number;
    secretsScanning: number;
  };
  mttr: {
    critical: number; // Mean time to remediate in hours
    high: number;
    medium: number;
  };
  compliance: {
    owaspTop10: number; // Percentage compliance
    pciDss: number;
    hipaa: number;
  };
}

export class SecurityMetricsCollector {
  private metricsHistory: SecurityMetrics[] = [];

  async collectMetrics(): Promise<SecurityMetrics> {
    const metrics: SecurityMetrics = {
      timestamp: new Date(),
      vulnerabilities: await this.countVulnerabilities(),
      coverage: await this.calculateCoverage(),
      mttr: await this.calculateMTTR(),
      compliance: await this.checkCompliance()
    };

    this.metricsHistory.push(metrics);
    return metrics;
  }

  private async countVulnerabilities(): Promise<SecurityMetrics['vulnerabilities']> {
    // Aggregate from all security tools
    return {
      total: 0,
      critical: 0,
      high: 0,
      medium: 0,
      low: 0
    };
  }

  private async calculateCoverage(): Promise<SecurityMetrics['coverage']> {
    return {
      sastCoverage: 85, // Percentage of code analyzed
      dastCoverage: 70, // Percentage of endpoints tested
      dependencyScanning: 100, // All dependencies scanned
      secretsScanning: 95 // Files scanned for secrets
    };
  }

  private async calculateMTTR(): Promise<SecurityMetrics['mttr']> {
    // Calculate from historical vulnerability data
    return {
      critical: 4, // 4 hours average for critical vulns
      high: 24,
      medium: 168 // 1 week
    };
  }

  private async checkCompliance(): Promise<SecurityMetrics['compliance']> {
    return {
      owaspTop10: 92,
      pciDss: 88,
      hipaa: 90
    };
  }

  generateDashboard(): string {
    const latest = this.metricsHistory[this.metricsHistory.length - 1];

    return `
# Security Dashboard

## Vulnerability Summary
- Critical: ${latest.vulnerabilities.critical}
- High: ${latest.vulnerabilities.high}
- Medium: ${latest.vulnerabilities.medium}
- Low: ${latest.vulnerabilities.low}

## Coverage
- SAST: ${latest.coverage.sastCoverage}%
- DAST: ${latest.coverage.dastCoverage}%
- Dependencies: ${latest.coverage.dependencyScanning}%
- Secrets: ${latest.coverage.secretsScanning}%

## Mean Time to Remediate
- Critical: ${latest.mttr.critical} hours
- High: ${latest.mttr.high} hours
- Medium: ${latest.mttr.medium} hours

## Compliance
- OWASP Top 10: ${latest.compliance.owaspTop10}%
- PCI-DSS: ${latest.compliance.pciDss}%
- HIPAA: ${latest.compliance.hipaa}%
    `;
  }
}

Security Scanning Best Practices

  • Shift left - Integrate security scanning early in development, not just before deployment
  • Layer defenses - Combine SAST, DAST, SCA, and container scanning for comprehensive coverage
  • Prioritize intelligently - Focus on reachable, exploitable vulnerabilities first
  • Automate remediation - Use AI to generate patches and Dependabot for dependency updates
  • Measure continuously - Track MTTR, vulnerability trends, and compliance metrics
  • Context matters - Not all vulnerabilities are equal; assess actual risk to your application

Implementing Shift-Left Security

Shift-left security integrates security checks as early as possible in development:

// Pre-commit hook for security checks
// .husky/pre-commit
#!/bin/sh

echo "Running security checks..."

# Check for secrets
npx secretlint "**/*"
if [ $? -ne 0 ]; then
  echo "Secrets detected! Please remove before committing."
  exit 1
fi

# Run security linting
npm run lint:security
if [ $? -ne 0 ]; then
  echo "Security issues found! Please fix before committing."
  exit 1
fi

# Check dependencies
npm audit --audit-level=high
if [ $? -ne 0 ]; then
  echo "High severity vulnerabilities in dependencies!"
  exit 1
fi

echo "Security checks passed!"
// package.json security scripts
{
  "scripts": {
    "security:check": "npm run security:sast && npm run security:deps && npm run security:secrets",
    "security:sast": "eslint --config .eslintrc.security.js src/",
    "security:deps": "npm audit --audit-level=moderate",
    "security:secrets": "secretlint **/*",
    "security:full": "npm run security:check && snyk test && snyk code test",
    "lint:security": "eslint --config .eslintrc.security.js --fix src/"
  }
}

Conclusion

AI-powered security scanning transforms how we identify and remediate vulnerabilities. By combining tools like Snyk for comprehensive scanning, Dependabot for automated updates, and OWASP ZAP for dynamic testing, you create multiple layers of security defense. The key is integrating these tools seamlessly into your CI/CD pipeline and development workflow.

Remember that security is not a one-time activity but a continuous process. Use AI to accelerate vulnerability detection and patch generation, but always apply human judgment for risk assessment and prioritization. The goal is not zero vulnerabilities but managing risk effectively while maintaining development velocity.

In our next article, we'll explore AI for Performance Monitoring and Optimization, where you'll learn how to leverage AI tools for identifying performance bottlenecks, optimizing resource usage, and building self-healing systems.