--- name: building-vulnerability-dashboard-with-defectdojo description: Deploy DefectDojo as a centralized vulnerability management dashboard with scanner integrations, deduplication, metrics tracking, and Jira ticketing workflows. 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 --- # 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 ```bash # Clone DefectDojo repository git clone https://github.com/DefectDojo/django-DefectDojo.git cd django-DefectDojo # Start with Docker Compose (production mode) ./dc-up-d.sh # Alternative: manual Docker Compose docker compose up -d # Check service status docker compose ps # View initial admin credentials docker compose logs initializer 2>&1 | grep "Admin password" # Access DefectDojo at http://localhost:8080 ``` ### Environment Configuration ```bash # Key environment variables in docker-compose.yml DD_DATABASE_ENGINE=django.db.backends.postgresql DD_DATABASE_HOST=postgres DD_DATABASE_PORT=5432 DD_DATABASE_NAME=defectdojo DD_DATABASE_USER=defectdojo DD_DATABASE_PASSWORD= DD_ALLOWED_HOSTS=* DD_SECRET_KEY= DD_CREDENTIAL_AES_256_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 ```python import requests DD_URL = "http://localhost:8080/api/v2" API_KEY = "your_api_key_here" HEADERS = {"Authorization": f"Token {API_KEY}", "Content-Type": "application/json"} # Create Product Type resp = 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 Product resp = 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 Engagement resp = 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 ```bash # Upload Nessus scan results curl -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 results curl -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 scan curl -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) ```yaml # .github/workflows/security-scan.yml name: Security Scan on: [push] jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Semgrep run: | pip install semgrep semgrep --config auto --json -o semgrep_results.json . - name: Upload to DefectDojo run: | 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 ```python # Configure Jira integration in DefectDojo settings jira_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 ```python # Get finding counts by severity resp = requests.get(f"{DD_URL}/findings/?limit=0&active=true", headers=HEADERS) findings = resp.json() # Get SLA breach counts resp = requests.get(f"{DD_URL}/findings/?limit=0&active=true&sla_breached=true", headers=HEADERS) # Get product-level metrics resp = requests.get(f"{DD_URL}/products/{product_id}/", headers=HEADERS) product_data = resp.json() ``` ## References - [DefectDojo GitHub](https://github.com/DefectDojo/django-DefectDojo) - [DefectDojo Documentation](https://defectdojo.github.io/django-DefectDojo/) - [DefectDojo REST API](https://defectdojo.github.io/django-DefectDojo/integrations/api-v2-docs/) - [OWASP DefectDojo Project](https://owasp.org/www-project-defectdojo/) - [DefectDojo Integrations](https://defectdojo.com/integrations)