# DefectDojo - Vulnerability Management

Comprehensive guide to vulnerability management, finding aggregation, and security orchestration with DefectDojo.

## Overview

**Container**: `defectdojo/defectdojo-django:latest`
**Category**: Vulnerability Management
**Port**: 8083
**URL**: http://localhost:8083

DefectDojo is an open-source application vulnerability management tool that streamlines the testing process by offering templating, report generation, metrics, and baseline self-service tools.

## Quick Start

```bash
# Access DefectDojo
open http://localhost:8083

# Default credentials (generated on first run)
# Check logs for initial admin password:
docker logs defectdojo 2>&1 | grep "Admin password"

# API Key location: User Menu → API v2 Key
```

## Core Concepts

| Concept | Description |
|---------|-------------|
| **Product** | Application or service being tested |
| **Engagement** | Testing activity (pentest, scan cycle) |
| **Test** | Specific scan or test within engagement |
| **Finding** | Individual vulnerability discovered |
| **Endpoint** | URLs, hosts, or services tested |

## Product Configuration

### Create Product

```bash
# Via API
curl -X POST "http://localhost:8083/api/v2/products/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Application",
    "description": "Production web application",
    "prod_type": 1,
    "business_criticality": "high",
    "platform": "web",
    "lifecycle": "production",
    "origin": "internal"
  }'
```

### Product Types

| Type | Description |
|------|-------------|
| Research and Development | Pre-release applications |
| Production | Live production systems |
| Third Party | Vendor applications |
| Enterprise | Internal enterprise apps |

## Engagements

### Create Engagement

```bash
curl -X POST "http://localhost:8083/api/v2/engagements/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q4 Security Assessment",
    "product": 1,
    "target_start": "2024-01-01",
    "target_end": "2024-01-31",
    "engagement_type": "CI/CD",
    "status": "In Progress",
    "deduplication_on_engagement": true
  }'
```

### Engagement Types

| Type | Use Case |
|------|----------|
| Interactive | Manual penetration testing |
| CI/CD | Automated pipeline scans |

## Importing Scan Results

### Supported Scan Types

| Scanner | Import Type | Notes |
|---------|-------------|-------|
| Semgrep | `Semgrep JSON Report` | SAST results |
| Trivy | `Trivy Scan` | Container/dependency scans |
| OWASP ZAP | `ZAP Scan` | DAST results |
| Nuclei | `Nuclei Scan` | Template-based scans |
| Gitleaks | `Gitleaks Scan` | Secret detection |
| Checkov | `Checkov Scan` | IaC security |
| SonarQube | `SonarQube API Import` | Code quality |
| Burp Suite | `Burp XML` | Web app testing |
| Nessus | `Nessus` | Network scanning |
| SARIF | `SARIF` | Generic SARIF format |

### Import via API

```bash
# Import Semgrep results
curl -X POST "http://localhost:8083/api/v2/import-scan/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -F "scan_type=Semgrep JSON Report" \
  -F "file=@semgrep-results.json" \
  -F "engagement=1" \
  -F "verified=false" \
  -F "active=true" \
  -F "minimum_severity=Info"

# Import Trivy results
curl -X POST "http://localhost:8083/api/v2/import-scan/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -F "scan_type=Trivy Scan" \
  -F "file=@trivy-results.json" \
  -F "engagement=1"

# Import ZAP results
curl -X POST "http://localhost:8083/api/v2/import-scan/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -F "scan_type=ZAP Scan" \
  -F "file=@zap-report.xml" \
  -F "engagement=1"

# Import Checkov results
curl -X POST "http://localhost:8083/api/v2/import-scan/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -F "scan_type=Checkov Scan" \
  -F "file=@checkov-results.json" \
  -F "engagement=1"
```

### Reimport (Update Existing)

```bash
# Reimport to update existing test
curl -X POST "http://localhost:8083/api/v2/reimport-scan/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -F "scan_type=Semgrep JSON Report" \
  -F "file=@semgrep-results.json" \
  -F "test=1" \
  -F "do_not_reactivate=false"
```

## Finding Management

### Severity Levels

| Severity | Score Range | SLA (Days) |
|----------|-------------|------------|
| Critical | 9.0 - 10.0 | 7 |
| High | 7.0 - 8.9 | 30 |
| Medium | 4.0 - 6.9 | 90 |
| Low | 0.1 - 3.9 | 180 |
| Info | 0.0 | None |

### Finding States

| State | Description |
|-------|-------------|
| Active | Currently unresolved |
| Verified | Confirmed by tester |
| Mitigated | Fix applied, awaiting verification |
| False Positive | Incorrectly identified |
| Out of Scope | Not applicable |
| Risk Accepted | Accepted business risk |
| Duplicate | Same as another finding |

### Query Findings

```bash
# Get all critical findings
curl -X GET "http://localhost:8083/api/v2/findings/?severity=Critical&active=true" \
  -H "Authorization: Token YOUR_API_KEY"

# Get findings by product
curl -X GET "http://localhost:8083/api/v2/findings/?test__engagement__product=1" \
  -H "Authorization: Token YOUR_API_KEY"

# Get findings with SLA breach
curl -X GET "http://localhost:8083/api/v2/findings/?sla_breached=true" \
  -H "Authorization: Token YOUR_API_KEY"
```

### Update Finding

```bash
# Mark as mitigated
curl -X PATCH "http://localhost:8083/api/v2/findings/123/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "is_mitigated": true,
    "mitigated": "2024-01-15T10:00:00Z",
    "mitigated_by": 1
  }'

# Mark as false positive
curl -X PATCH "http://localhost:8083/api/v2/findings/123/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "false_p": true,
    "active": false
  }'
```

## Deduplication

### Configuration

DefectDojo supports multiple deduplication algorithms:

| Algorithm | Description |
|-----------|-------------|
| Legacy | Hash-based (title + description) |
| Unique ID from Tool | Uses scanner's unique ID |
| Unique ID from Tool or Hash | Combination approach |
| Algorithm-based | CWE + file + line number |

### Deduplication Settings

```python
# settings.py (Docker environment)
DD_DUPLICATE_FINDER_LEGACY_ENABLED=True
DD_DUPLICATE_FINDER_UNIQUE_ID_FROM_TOOL=True
DD_DUPLICATE_FINDER_HASH_CODE=True
DD_DUPLICATE_FINDER_ALGORITHM=True
```

## Reports

### Generate Report

```bash
# Product report
curl -X GET "http://localhost:8083/api/v2/products/1/generate_report/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -o product_report.pdf

# Engagement report
curl -X GET "http://localhost:8083/api/v2/engagements/1/generate_report/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -o engagement_report.pdf
```

### Report Types

| Type | Content |
|------|---------|
| Executive | High-level summary for leadership |
| Product | All findings for a product |
| Engagement | Findings from specific engagement |
| Test | Findings from single test |

## Metrics & Dashboards

### Key Metrics

| Metric | Description |
|--------|-------------|
| Mean Time to Remediation | Average fix time |
| Open Finding Count | Active vulnerabilities |
| SLA Compliance | Findings fixed within SLA |
| Finding Trend | New vs closed over time |
| Severity Distribution | Breakdown by severity |

### API Metrics

```bash
# Product metrics
curl -X GET "http://localhost:8083/api/v2/products/1/metrics/" \
  -H "Authorization: Token YOUR_API_KEY"

# Finding count by severity
curl -X GET "http://localhost:8083/api/v2/findings/?limit=0" \
  -H "Authorization: Token YOUR_API_KEY" | jq '.count'
```

## CI/CD Integration

### GitHub Actions

```yaml
name: Security Pipeline
on: [push]

jobs:
  scan-and-import:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Run Semgrep
        run: |
          docker run --rm -v ${PWD}:/src returntocorp/semgrep \
            semgrep --config auto --json -o semgrep.json /src

      - name: Import to DefectDojo
        run: |
          curl -X POST "${{ secrets.DEFECTDOJO_URL }}/api/v2/import-scan/" \
            -H "Authorization: Token ${{ secrets.DEFECTDOJO_TOKEN }}" \
            -F "scan_type=Semgrep JSON Report" \
            -F "file=@semgrep.json" \
            -F "engagement=${{ secrets.ENGAGEMENT_ID }}" \
            -F "verified=false"
```

### Pipeline Integration Script

```bash
#!/bin/bash
# import-all-scans.sh

DEFECTDOJO_URL="http://localhost:8083"
API_KEY="your-api-key"
ENGAGEMENT_ID="1"

# Import Semgrep
if [ -f "semgrep.json" ]; then
    curl -X POST "$DEFECTDOJO_URL/api/v2/import-scan/" \
        -H "Authorization: Token $API_KEY" \
        -F "scan_type=Semgrep JSON Report" \
        -F "file=@semgrep.json" \
        -F "engagement=$ENGAGEMENT_ID"
fi

# Import Trivy
if [ -f "trivy.json" ]; then
    curl -X POST "$DEFECTDOJO_URL/api/v2/import-scan/" \
        -H "Authorization: Token $API_KEY" \
        -F "scan_type=Trivy Scan" \
        -F "file=@trivy.json" \
        -F "engagement=$ENGAGEMENT_ID"
fi

# Import ZAP
if [ -f "zap-report.xml" ]; then
    curl -X POST "$DEFECTDOJO_URL/api/v2/import-scan/" \
        -H "Authorization: Token $API_KEY" \
        -F "scan_type=ZAP Scan" \
        -F "file=@zap-report.xml" \
        -F "engagement=$ENGAGEMENT_ID"
fi

# Import Gitleaks
if [ -f "gitleaks.json" ]; then
    curl -X POST "$DEFECTDOJO_URL/api/v2/import-scan/" \
        -H "Authorization: Token $API_KEY" \
        -F "scan_type=Gitleaks Scan" \
        -F "file=@gitleaks.json" \
        -F "engagement=$ENGAGEMENT_ID"
fi

echo "All scans imported to DefectDojo"
```

## JIRA Integration

### Configuration

```python
# Enable JIRA in settings
JIRA_ENABLED=True
JIRA_URL="https://company.atlassian.net"
JIRA_USERNAME="jira@company.com"
JIRA_API_KEY="your-jira-api-key"
```

### Push Finding to JIRA

```bash
# Create JIRA issue from finding
curl -X POST "http://localhost:8083/api/v2/findings/123/jira/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "push_to_jira": true
  }'
```

## Notifications

### Webhook Integration

```bash
# Create webhook endpoint
curl -X POST "http://localhost:8083/api/v2/system_settings/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enable_webhooks": true,
    "webhook_url": "https://hooks.slack.com/services/xxx",
    "webhook_events": ["finding_created", "finding_mitigated"]
  }'
```

### Slack Notifications

```python
# settings.py
SLACK_TOKEN = "xoxb-your-token"
SLACK_CHANNEL = "#security-alerts"
```

## Best Practices

1. **Product Structure** - Create products for each application
2. **Regular Imports** - Automate scan imports in CI/CD
3. **Deduplication** - Configure appropriate algorithm for scanner
4. **SLA Tracking** - Set realistic SLAs by severity
5. **Risk Acceptance** - Document accepted risks with justification
6. **Integration** - Connect to JIRA for tracking
7. **Reports** - Generate regular executive reports
8. **Cleanup** - Archive old engagements and products
9. **API Keys** - Rotate API keys regularly
10. **Backups** - Regular database backups

## Integration with Stack

- Import Semgrep, Trivy, ZAP, Nuclei, Gitleaks results
- Import Checkov IaC scan results
- Import Syft SBOM analysis
- Correlate Falco runtime alerts
- Track findings from RESTler fuzzing
- Aggregate all security findings in one place
- Generate unified security reports

## Troubleshooting

### Common Issues

**Issue**: Import fails with parser error
```bash
# Check scan format matches scan_type
# Verify JSON/XML is valid
jq . semgrep-results.json
```

**Issue**: Duplicate findings not merged
```bash
# Check deduplication settings
# Ensure same product/engagement
# Verify hash algorithm configuration
```

**Issue**: API authentication fails
```bash
# Regenerate API key
# Check token format: "Token YOUR_KEY"
# Verify user has API permissions
```
