Overview
DefectDojo is an open-source vulnerability management platform that streamlines the tracking, deduplication, and management of security findings from multiple scanning tools. It provides metrics, reporting, and integration capabilities for security operations and compliance workflows.
Installation
Docker Installation
# Clone DefectDojo repository
git clone https://github.com/DefectDojo/django-DefectDojo.git
cd django-DefectDojo
# Using docker-compose (recommended for development)
docker-compose up -d
# Access at http://localhost:8000
# Default credentials: admin / admin (change immediately in production)
Kubernetes Installation
# Add DefectDojo Helm repository
helm repo add defectdojo https://defectdojo.github.io/helm-charts
helm repo update
# Install DefectDojo
helm install defectdojo defectdojo/defectdojo \
--namespace defectdojo \
--create-namespace \
--values values.yaml
# Forward port for access
kubectl port-forward -n defectdojo svc/defectdojo 8000:8000
Source Installation
# Clone repository
git clone https://github.com/DefectDojo/django-DefectDojo.git
cd django-DefectDojo
# Install dependencies
pip install -r requirements.txt
# Initialize database
python manage.py migrate
# Create superuser
python manage.py createsuperuser
# Collect static files
python manage.py collectstatic --noinput
# Run development server
python manage.py runserver
Initial Setup
Configuration
# Environment variables (.env)
DEBUG=False
SECRET_KEY=your-secret-key-here
DB_ENGINE=django.db.backends.postgresql
DB_NAME=defectdojo
DB_USER=defectdojo
DB_PASSWORD=secure-password
DB_HOST=postgres
ALLOWED_HOSTS=localhost,127.0.0.1,your-domain.com
First Steps
- Change default admin password
- Configure authentication (LDAP, OAuth, SAML)
- Set up notification channels (email, Slack, etc.)
- Create product types and templates
- Configure scanner credentials
- Set up system settings and SLA policies
Product/Engagement/Test Hierarchy
Core Structure
| Level | Purpose | Description |
|---|
| Product | Container | High-level application or service |
| Engagement | Testing cycle | Time-bound security testing activity |
| Test | Scan result | Individual scanner output within engagement |
| Finding | Vulnerability | Specific security issue or flaw |
Creating Products
Dashboard → Products → New Product
- Product Name
- Product Type (Web App, API, Mobile, etc.)
- Description
- SLA choice
- Enable/disable various tracking options
Creating Engagements
Product → New Engagement
- Engagement Name
- Engagement Type (Baseline, Targeted, Incident, etc.)
- Start Date
- End Date (optional, for scoped tests)
- Lead
- Status (Scheduled, In Progress, Completed, etc.)
- Engagement Type Template (optional)
Adding Tests
Engagement → Add Test
- Test Type (Nessus, Burp, OWASP ZAP, Trivy, etc.)
- Scan Date
- Environment (Development, Staging, Production)
- Scan Status
- Upload findings via file or API
Importing Scan Results
Supported Scanners
| Scanner | Format | Notes |
|---|
| Nessus | .nessus XML | Network vulnerability scanner |
| Burp Suite | Burp XML | Web application security |
| OWASP ZAP | XML/JSON | Dynamic web app scanning |
| Trivy | JSON/SARIF | Container/artifact scanning |
| Nuclei | JSON | Fast vulnerability scanner |
| Sonarqube | JSON | Code quality & SAST |
| Checkmarx | XML | Enterprise SAST |
| Fortify | FPR/XML | Static security analysis |
| Snyk | JSON | Open source vulnerability |
| Qualys | XML | Vulnerability management |
Import Methods
# Web UI Import
Engagement → Test → Import Scan Results
- Select Parser (auto-detected)
- Upload scan file
- Verify deduplication settings
- Confirm import
# API Import
curl -X POST \
-H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d @scan-results.json \
http://localhost:8000/api/v2/import-scan/
Bulk Import
# Using API for multiple scans
for file in scans/*.xml; do
curl -X POST \
-H "Authorization: Token YOUR_API_TOKEN" \
-F "file=@$file" \
-F "test=TEST_ID" \
http://localhost:8000/api/v2/import-scan/
done
Vulnerability Deduplication
Deduplication Strategy
Settings → System Settings → Deduplication
- Enable/disable deduplication
- Hash algorithm (MD5, SHA256)
- Manual deduplication mode
- Clustering method
Manual Deduplication
Product → Findings
- Select multiple findings
- Merge duplicates
- Keep one as primary
- Link duplicates
- Update status consistently
Hash-Based Deduplication
DefectDojo automatically creates hashes from:
- File path + line number + CWE
- Endpoint + parameter
- IP + port + issue type
Duplicate findings are grouped and displayed together.
Risk Acceptance
Creating Risk Acceptance
Finding → Actions → Accept Risk
- Risk Acceptance Name
- Justification/Reason
- Decision Date
- Expiration Date (optional)
- Accepted by (user)
- Recommended/Required fields
Bulk Risk Acceptance
Product → Findings → Select Multiple
- Bulk Actions → Accept Risk
- Apply same justification to all
- Set expiration policy
Risk Acceptance Reports
Product → Metrics → Risk Acceptance
- View accepted vs. open findings
- Export risk acceptance summary
- Track acceptance history
- Monitor expiration dates
Metrics and Reporting
Dashboard Metrics
| Metric | Purpose |
|---|
| Open Vulnerabilities | Current unfixed findings |
| Fixed Vulnerabilities | Resolved issues (30/60/90 day) |
| Average CVSS Score | Risk severity trending |
| Findings by Severity | Critical/High/Medium/Low breakdown |
| Remediation Rate | Percentage of closed findings |
| Mean Time to Remediation | Average fix duration |
Report Generation
Product → Reports → Generate Report
- Report Type (Detailed, Executive, Compliance)
- Date Range
- Include: Findings, Metrics, Risk Acceptance
- Export Format (PDF, Excel, JSON)
- Schedule recurring reports
Custom Reports
Settings → Report Templates
- Create custom report layout
- Select sections/widgets
- Add company branding
- Define data filters
- Schedule automated delivery
API Usage
Authentication
# Generate API token
Settings → API Tokens → Create Token
# Use in requests
curl -H "Authorization: Token YOUR_API_TOKEN" \
http://localhost:8000/api/v2/products/
Common Endpoints
# List products
GET /api/v2/products/
# Get product details
GET /api/v2/products/{id}/
# List engagements for product
GET /api/v2/engagements/?product={product_id}
# List findings
GET /api/v2/findings/?product={product_id}&status=Open
# Create finding
POST /api/v2/findings/
{
"title": "SQL Injection",
"test": 123,
"severity": "High",
"cwe": 89
}
# Update finding
PATCH /api/v2/findings/{id}/
# Import scan results
POST /api/v2/import-scan/
# All API endpoints support pagination
GET /api/v2/findings/?limit=50&offset=0
# Get total count
GET /api/v2/findings/?limit=1
# Returns: count: 12345
CI/CD Integration
Jenkins Integration
// Jenkinsfile
pipeline {
stages {
stage('Security Scan') {
steps {
sh './zap-scan.sh'
sh 'curl -X POST \
-H "Authorization: Token ${DEFECTDOJO_TOKEN}" \
-F "file=@zap-report.xml" \
-F "test=123" \
http://defectdojo.example.com/api/v2/import-scan/'
}
}
}
}
GitHub Actions
name: Security Scan
on: [push]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Trivy scan
run: trivy image --format json -o trivy-report.json myimage:latest
- name: Upload to DefectDojo
run: |
curl -X POST \
-H "Authorization: Token ${{ secrets.DEFECTDOJO_TOKEN }}" \
-F "file=@trivy-report.json" \
-F "test=${{ env.TEST_ID }}" \
${{ secrets.DEFECTDOJO_URL }}/api/v2/import-scan/
GitLab CI
stages:
- security
sast_scan:
image: aquasec/trivy:latest
stage: security
script:
- trivy image --format json -o report.json $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- |
curl -X POST \
-H "Authorization: Token $DEFECTDOJO_TOKEN" \
-F "file=@report.json" \
-F "test=$TEST_ID" \
$DEFECTDOJO_URL/api/v2/import-scan/
JIRA Integration
Setup
Settings → Integrations → JIRA
- JIRA URL
- Username/Token
- Project Key
- Issue Type (Bug, Task, etc.)
- Custom field mapping
Create JIRA Issue
Finding → Actions → Create JIRA Issue
- Auto-creates ticket with:
- Finding title & description
- Severity mapped to priority
- CWE & CVSS details
- Link back to DefectDojo
Bulk JIRA Creation
Product → Findings → Select Multiple
- Bulk Actions → Create JIRA Issues
- Apply same priority/assignment
- Template comments
Sync Status
Settings → Integrations → JIRA
- Enable bi-directional sync
- Auto-close finding when ticket resolved
- Update finding when ticket status changes
SLA Management
Settings → System Settings → SLA
- Define SLA for each severity:
- Critical: 7 days
- High: 30 days
- Medium: 60 days
- Low: 90 days
SLA Tracking
Product → Metrics → SLA Status
- View findings past SLA
- Identify aging vulnerabilities
- Generate SLA breach reports
- Track remediation trends
SLA Thresholds
| Severity | Recommended SLA |
|---|
| Critical | 7 days |
| High | 14-30 days |
| Medium | 30-60 days |
| Low | 60-90 days |
User Roles and Permissions
Default Roles
| Role | Permissions |
|---|
| Admin | Full system access, user management, settings |
| Product Owner | Product management, engagement creation, finding updates |
| Analyst | View/edit findings, run reports, comment |
| Reporter | View-only access, report generation |
| Service Account | API-only access, limited scopes |
Creating Custom Roles
Settings → Permissions → Roles
- Define role name
- Select permissions:
- View products
- Add findings
- Accept risk
- Create engagements
- Export reports
- Manage users
Product Permissions
Product → Settings → Permissions
- Product Owner
- Analysts (multiple)
- Stakeholders (view-only)
- JIRA project leads
Role Assignment
Settings → Users → Select User
- Global role (Admin, Product Owner, etc.)
- Product-specific role
- Engagement-level access
- API token scopes
Best Practices
Finding Management
- Review & Deduplicate: Consolidate duplicate findings immediately after import
- Set Severity: Ensure accurate CVSS/severity classification
- Add Context: Document root cause and remediation steps
- Track Progress: Update status (Open, In Progress, Fixed, Accepted)
- Verify Fixes: Re-scan after remediation to confirm closure
Engagement Planning
- Baseline Tests: Initial comprehensive assessment
- Targeted Tests: Focus on specific components/changes
- Regression Tests: Verify previous fixes weren’t reintroduced
- Incident Testing: Rapid assessment after security events
Reporting
- Executive Reports: Metrics, trends, risk summary
- Technical Reports: Detailed findings, remediation guidance
- Compliance Reports: Evidence for audits, certifications
- SLA Reports: Remediation tracking, aging vulnerabilities
Integration
- Automate Imports: Schedule scans to auto-import results
- Notify Teams: Set up alerts for critical findings
- JIRA Workflow: Automatic ticket creation and sync
- API Usage: Extract data for custom dashboards
Troubleshooting
Common Issues
| Issue | Solution |
|---|
| Import fails | Verify scanner format, check parser compatibility, validate XML |
| Slow deduplication | Disable hash-based dedup, perform manual cleanup |
| API rate limits | Implement backoff, batch requests, upgrade rate limits |
| Memory issues | Increase Java heap, reduce bulk operations size |
| LDAP auth fails | Verify credentials, check LDAP config, test connection |
Useful Commands
# Check system status
docker-compose logs defectdojo
# Clear old findings (bulk cleanup)
python manage.py shell
>>> Finding.objects.filter(date__lt='2023-01-01').delete()
# Reset admin password
python manage.py changepassword admin
# Backup database
pg_dump defectdojo > backup.sql