Skill v1.0.0
currentAutomated scan100/100name: building-vulnerability-dashboard-with-defectdojo description: Deploy DefectDojo as a centralized vulnerability management dashboard that ingests findings from 200+ security scanners, deduplicates results, tracks remediation metrics, and integrates with CI/CD, Jira ticketing, and Slack notifications via its REST API. Use when consolidating scanner output into one dashboard or automating vulnerability ticketing and executive reporting. domain: cybersecurity subdomain: vulnerability-management tags:
- defectdojo
- vulnerability-management
- dashboard
- deduplication
- scanner-integration
- devsecops
- jira
version: '1.0' author: mahipal license: Apache-2.0 nist_csf:
- ID.RA-01
- ID.RA-02
- ID.IM-02
- ID.RA-06
mitre_attack:
- T1190
- T1203
- T1068
Building Vulnerability Dashboard with DefectDojo
Overview
DefectDojo is an open-source application vulnerability management platform that aggregates findings from 200+ security tools, deduplicates results, tracks remediation progress, and provides executive dashboards. It serves as a central hub for vulnerability management, integrating with CI/CD pipelines, Jira for ticketing, and Slack for notifications. DefectDojo supports OWASP-based categorization and provides REST API for automation.
When to Use
- When deploying or configuring building vulnerability dashboard with defectdojo capabilities in your environment
- When establishing security controls aligned to compliance requirements
- When building or improving security architecture for this domain
- When conducting security assessments that require this implementation
Prerequisites
- Docker and Docker Compose
- 4GB+ RAM, 2+ CPU cores, 20GB+ disk
- PostgreSQL 12+ (included in Docker deployment)
- Python 3.9+ for API integration scripts
- Jira instance (optional, for ticket integration)
Deployment
Docker Compose Deployment
# Clone DefectDojo repositorygit clone https://github.com/DefectDojo/django-DefectDojo.gitcd django-DefectDojo# Start with Docker Compose (production mode)./dc-up-d.sh# Alternative: manual Docker Composedocker compose up -d# Check service statusdocker compose ps# View initial admin credentialsdocker compose logs initializer 2>&1 | grep "Admin password"# Access DefectDojo at http://localhost:8080
Environment Configuration
# Key environment variables in docker-compose.ymlDD_DATABASE_ENGINE=django.db.backends.postgresqlDD_DATABASE_HOST=postgresDD_DATABASE_PORT=5432DD_DATABASE_NAME=defectdojoDD_DATABASE_USER=defectdojoDD_DATABASE_PASSWORD=<secure_password>DD_ALLOWED_HOSTS=*DD_SECRET_KEY=<random_64_char_key>DD_CREDENTIAL_AES_256_KEY=<random_128_bit_key>DD_SOCIAL_AUTH_GOOGLE_OAUTH2_ENABLED=True
Organizational Structure
Hierarchy
Product Type (Business Unit)└── Product (Application/Service)└── Engagement (Assessment/Sprint)└── Test (Scanner Run)└── Finding (Individual Vulnerability)
Setup via API
import requestsDD_URL = "http://localhost:8080/api/v2"API_KEY = "your_api_key_here"HEADERS = {"Authorization": f"Token {API_KEY}", "Content-Type": "application/json"}# Create Product Typeresp = requests.post(f"{DD_URL}/product_types/", headers=HEADERS, json={"name": "Web Applications","description": "Customer-facing web application portfolio"})product_type_id = resp.json()["id"]# Create Productresp = requests.post(f"{DD_URL}/products/", headers=HEADERS, json={"name": "Customer Portal","description": "Main customer-facing web application","prod_type": product_type_id,"sla_configuration": 1,})product_id = resp.json()["id"]# Create Engagementresp = requests.post(f"{DD_URL}/engagements/", headers=HEADERS, json={"name": "Q1 2024 Security Assessment","product": product_id,"target_start": "2024-01-01","target_end": "2024-03-31","engagement_type": "CI/CD","status": "In Progress",})engagement_id = resp.json()["id"]
Scanner Integration
Import Scan Results via API
# Upload Nessus scan resultscurl -X POST "${DD_URL}/reimport-scan/" \-H "Authorization: Token ${API_KEY}" \-F "scan_type=Nessus Scan" \-F "file=@nessus_report.csv" \-F "product_name=Customer Portal" \-F "engagement_name=Q1 2024 Security Assessment" \-F "auto_create_context=true" \-F "deduplication_on_engagement=true"# Upload OWASP ZAP resultscurl -X POST "${DD_URL}/reimport-scan/" \-H "Authorization: Token ${API_KEY}" \-F "scan_type=ZAP Scan" \-F "file=@zap_report.xml" \-F "product_name=Customer Portal" \-F "engagement_name=Q1 2024 Security Assessment" \-F "auto_create_context=true"# Upload Trivy container scancurl -X POST "${DD_URL}/reimport-scan/" \-H "Authorization: Token ${API_KEY}" \-F "scan_type=Trivy Scan" \-F "file=@trivy_results.json" \-F "product_name=Customer Portal" \-F "engagement_name=Q1 2024 Security Assessment" \-F "auto_create_context=true"
Supported Scanner Types (Partial List)
| Scanner | Type String | Format | |
|---|---|---|---|
| Nessus | Nessus Scan | CSV/XML | |
| OpenVAS | OpenVAS CSV | CSV | |
| Qualys | Qualys Scan | XML | |
| OWASP ZAP | ZAP Scan | XML/JSON | |
| Burp Suite | Burp XML | XML | |
| Trivy | Trivy Scan | JSON | |
| Semgrep | Semgrep JSON Report | JSON | |
| Snyk | Snyk Scan | JSON | |
| SonarQube | SonarQube Scan | JSON | |
| Checkov | Checkov Scan | JSON |
CI/CD Integration (GitHub Actions)
# .github/workflows/security-scan.ymlname: Security Scanon: [push]jobs:scan:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Run Semgreprun: |pip install semgrepsemgrep --config auto --json -o semgrep_results.json .- name: Upload to DefectDojorun: |curl -X POST "${{ secrets.DD_URL }}/api/v2/reimport-scan/" \-H "Authorization: Token ${{ secrets.DD_API_KEY }}" \-F "scan_type=Semgrep JSON Report" \-F "file=@semgrep_results.json" \-F "product_name=${{ github.event.repository.name }}" \-F "engagement_name=CI/CD" \-F "auto_create_context=true"
Jira Integration
# Configure Jira integration in DefectDojo settingsjira_config = {"url": "https://company.atlassian.net","username": "jira-bot@company.com","password": "jira_api_token","default_issue_type": "Bug","critical_mapping_severity": "Blocker","high_mapping_severity": "Critical","medium_mapping_severity": "Major","low_mapping_severity": "Minor","finding_text": "**Vulnerability**: {{ finding.title }}\n**Severity**: {{ finding.severity }}\n**CVE**: {{ finding.cve }}\n**Description**: {{ finding.description }}","accepted_mapping_resolution": "Done","close_status_key": 6,}
Metrics and Dashboards
Key Metrics API Queries
# Get finding counts by severityresp = requests.get(f"{DD_URL}/findings/?limit=0&active=true",headers=HEADERS)findings = resp.json()# Get SLA breach countsresp = requests.get(f"{DD_URL}/findings/?limit=0&active=true&sla_breached=true",headers=HEADERS)# Get product-level metricsresp = requests.get(f"{DD_URL}/products/{product_id}/",headers=HEADERS)product_data = resp.json()