NVD Integration
This example demonstrates how to integrate with the National Vulnerability Database (NVD) to download, process, and use CPE data for vulnerability management.
Overview
The National Vulnerability Database (NVD) provides comprehensive CPE dictionaries and vulnerability data. This integration allows you to download official CPE data, keep it updated, and use it for vulnerability assessment.
Complete Example
go
package main
import (
"fmt"
"log"
"time"
"github.com/scagogogo/cpe"
)
func main() {
fmt.Println("=== NVD Integration Examples ===")
// Example 1: Download NVD CPE Dictionary
fmt.Println("\n1. Downloading NVD CPE Dictionary:")
// Initialize NVD client
nvdClient := cpe.NewNVDClient(&cpe.NVDConfig{
APIKey: "", // Optional: Add your NVD API key for higher rate limits
CacheDir: "./nvd_cache",
UpdateInterval: 24 * time.Hour, // Update daily
})
// Download the latest CPE dictionary
fmt.Println("Downloading CPE dictionary from NVD...")
dictionary, err := nvdClient.DownloadCPEDictionary()
if err != nil {
log.Printf("Failed to download CPE dictionary: %v", err)
// For demo purposes, create a sample dictionary
dictionary = createSampleDictionary()
} else {
fmt.Printf("✅ Downloaded %d CPE entries\n", len(dictionary.Entries))
}
// Example 2: Search CPE Dictionary
fmt.Println("\n2. Searching CPE Dictionary:")
searchTerms := []string{
"microsoft",
"apache",
"oracle java",
"linux kernel",
"cisco",
}
for _, term := range searchTerms {
fmt.Printf("\nSearching for '%s':\n", term)
results := dictionary.Search(term, 5) // Limit to 5 results
for i, entry := range results {
fmt.Printf(" %d. %s\n", i+1, entry.CPE23)
fmt.Printf(" Title: %s\n", entry.Title)
if len(entry.References) > 0 {
fmt.Printf(" Reference: %s\n", entry.References[0])
}
}
}
// Example 3: CPE Validation Against NVD
fmt.Println("\n3. CPE Validation Against NVD:")
testCPEs := []string{
"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*",
"cpe:2.3:a:apache:tomcat:9.0.0:*:*:*:*:*:*:*",
"cpe:2.3:a:oracle:java:11.0.12:*:*:*:*:*:*:*",
"cpe:2.3:a:nonexistent:product:1.0:*:*:*:*:*:*:*", // Invalid CPE
}
fmt.Println("Validating CPEs against NVD dictionary:")
for i, cpeStr := range testCPEs {
isValid := dictionary.ValidateCPE(cpeStr)
status := "❌ Invalid"
if isValid {
status = "✅ Valid"
}
fmt.Printf(" %d. %s %s\n", i+1, status, cpeStr)
// Get additional information if valid
if isValid {
entry := dictionary.GetEntry(cpeStr)
if entry != nil {
fmt.Printf(" Title: %s\n", entry.Title)
fmt.Printf(" Last Modified: %s\n", entry.LastModified.Format("2006-01-02"))
}
}
}
// Example 4: Download Vulnerability Data
fmt.Println("\n4. Downloading Vulnerability Data:")
// Download recent CVE data
fmt.Println("Downloading recent CVE data...")
cveData, err := nvdClient.DownloadCVEData(time.Now().AddDate(0, -1, 0)) // Last month
if err != nil {
log.Printf("Failed to download CVE data: %v", err)
// Create sample CVE data for demo
cveData = createSampleCVEData()
} else {
fmt.Printf("✅ Downloaded %d CVE entries\n", len(cveData.CVEs))
}
// Example 5: CPE to CVE Mapping
fmt.Println("\n5. CPE to CVE Mapping:")
// Find vulnerabilities for specific CPEs
targetCPEs := []string{
"cpe:2.3:a:apache:tomcat:8.5.0:*:*:*:*:*:*:*",
"cpe:2.3:a:oracle:java:8.0.291:*:*:*:*:*:*:*",
"cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*",
}
for _, cpeStr := range targetCPEs {
fmt.Printf("\nFinding vulnerabilities for: %s\n", cpeStr)
vulnerabilities := cveData.FindVulnerabilitiesForCPE(cpeStr)
if len(vulnerabilities) == 0 {
fmt.Println(" No vulnerabilities found")
} else {
fmt.Printf(" Found %d vulnerabilities:\n", len(vulnerabilities))
for i, vuln := range vulnerabilities[:min(3, len(vulnerabilities))] { // Show first 3
fmt.Printf(" %d. %s (CVSS: %.1f)\n", i+1, vuln.ID, vuln.CVSSScore)
fmt.Printf(" %s\n", vuln.Description)
fmt.Printf(" Published: %s\n", vuln.PublishedDate.Format("2006-01-02"))
}
if len(vulnerabilities) > 3 {
fmt.Printf(" ... and %d more\n", len(vulnerabilities)-3)
}
}
}
// Example 6: Vulnerability Assessment
fmt.Println("\n6. Vulnerability Assessment:")
// Assess a system inventory
systemInventory := []string{
"cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*",
"cpe:2.3:a:apache:tomcat:8.5.0:*:*:*:*:*:*:*",
"cpe:2.3:a:oracle:java:8.0.291:*:*:*:*:*:*:*",
"cpe:2.3:a:microsoft:office:2019:*:*:*:*:*:*:*",
"cpe:2.3:a:mozilla:firefox:95.0:*:*:*:*:*:*:*",
}
fmt.Println("System Vulnerability Assessment:")
fmt.Printf("Inventory: %d components\n", len(systemInventory))
assessment := cpe.NewVulnerabilityAssessment()
totalVulns := 0
criticalVulns := 0
highVulns := 0
for _, cpeStr := range systemInventory {
vulns := cveData.FindVulnerabilitiesForCPE(cpeStr)
totalVulns += len(vulns)
for _, vuln := range vulns {
switch {
case vuln.CVSSScore >= 9.0:
criticalVulns++
case vuln.CVSSScore >= 7.0:
highVulns++
}
}
assessment.AddComponent(cpeStr, vulns)
}
fmt.Printf("\nAssessment Results:\n")
fmt.Printf(" Total Vulnerabilities: %d\n", totalVulns)
fmt.Printf(" Critical (CVSS 9.0+): %d\n", criticalVulns)
fmt.Printf(" High (CVSS 7.0-8.9): %d\n", highVulns)
fmt.Printf(" Risk Score: %.1f/10\n", assessment.CalculateRiskScore())
// Example 7: Automated Updates
fmt.Println("\n7. Automated Updates:")
// Set up automatic updates
updateConfig := &cpe.UpdateConfig{
CheckInterval: 6 * time.Hour, // Check every 6 hours
AutoDownload: true,
NotifyOnUpdate: true,
}
updater := cpe.NewNVDUpdater(nvdClient, updateConfig)
fmt.Println("Setting up automated NVD updates...")
// Check for updates
hasUpdates, err := updater.CheckForUpdates()
if err != nil {
log.Printf("Failed to check for updates: %v", err)
} else {
if hasUpdates {
fmt.Println("✅ Updates available")
// Download updates
fmt.Println("Downloading updates...")
err = updater.DownloadUpdates()
if err != nil {
log.Printf("Failed to download updates: %v", err)
} else {
fmt.Println("✅ Updates downloaded successfully")
}
} else {
fmt.Println("📅 No updates available")
}
}
// Example 8: Custom NVD Queries
fmt.Println("\n8. Custom NVD Queries:")
// Query for specific vulnerability types
queries := []struct {
name string
query cpe.NVDQuery
}{
{
"Recent Critical Vulnerabilities",
cpe.NVDQuery{
CVSSScoreMin: 9.0,
PublishedAfter: time.Now().AddDate(0, -3, 0), // Last 3 months
Limit: 10,
},
},
{
"Apache Product Vulnerabilities",
cpe.NVDQuery{
CPEVendor: "apache",
CVSSScoreMin: 7.0,
Limit: 5,
},
},
{
"Windows OS Vulnerabilities",
cpe.NVDQuery{
CPEProduct: "windows",
CPEPart: "o", // Operating system
Limit: 5,
},
},
}
for _, q := range queries {
fmt.Printf("\n%s:\n", q.name)
results, err := nvdClient.QueryVulnerabilities(q.query)
if err != nil {
log.Printf("Query failed: %v", err)
continue
}
if len(results) == 0 {
fmt.Println(" No results found")
} else {
for i, vuln := range results {
fmt.Printf(" %d. %s (CVSS: %.1f)\n", i+1, vuln.ID, vuln.CVSSScore)
fmt.Printf(" %s\n", truncateString(vuln.Description, 80))
}
}
}
// Example 9: Export and Reporting
fmt.Println("\n9. Export and Reporting:")
// Generate vulnerability report
report := cpe.NewVulnerabilityReport()
report.SetTitle("System Vulnerability Assessment Report")
report.SetGeneratedDate(time.Now())
// Add system information
for _, cpeStr := range systemInventory {
vulns := cveData.FindVulnerabilitiesForCPE(cpeStr)
report.AddSystemComponent(cpeStr, vulns)
}
// Export to different formats
formats := []string{"json", "csv", "html"}
for _, format := range formats {
filename := fmt.Sprintf("vulnerability_report.%s", format)
err := report.ExportToFile(filename, format)
if err != nil {
log.Printf("Failed to export %s: %v", format, err)
} else {
fmt.Printf("✅ Report exported to %s\n", filename)
}
}
}
// Helper functions for demo
func createSampleDictionary() *cpe.CPEDictionary {
return &cpe.CPEDictionary{
Entries: []*cpe.CPEDictionaryEntry{
{
CPE23: "cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*",
Title: "Microsoft Windows 10",
LastModified: time.Now(),
},
{
CPE23: "cpe:2.3:a:apache:tomcat:9.0.0:*:*:*:*:*:*:*",
Title: "Apache Tomcat 9.0.0",
LastModified: time.Now(),
},
},
}
}
func createSampleCVEData() *cpe.CVEData {
return &cpe.CVEData{
CVEs: []*cpe.CVEEntry{
{
ID: "CVE-2021-44228",
Description: "Apache Log4j2 JNDI features do not protect against attacker controlled LDAP and other JNDI related endpoints.",
CVSSScore: 10.0,
PublishedDate: time.Date(2021, 12, 10, 0, 0, 0, 0, time.UTC),
AffectedCPEs: []string{
"cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*",
},
},
},
}
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func truncateString(s string, maxLen int) string {
if len(s) <= maxLen {
return s
}
return s[:maxLen-3] + "..."
}
Key Concepts
1. NVD Data Sources
- CPE Dictionary: Official CPE names and metadata
- CVE Data: Vulnerability information with CPE associations
- CVSS Scores: Vulnerability severity ratings
- References: Links to additional information
2. Integration Benefits
- Official Data: Authoritative CPE and vulnerability information
- Regular Updates: Keep data current with automated updates
- Comprehensive Coverage: Extensive database of software and vulnerabilities
- Standardized Format: Consistent data structure and naming
3. Use Cases
- Vulnerability Assessment: Identify security risks in systems
- Compliance Reporting: Generate security compliance reports
- Asset Management: Maintain accurate software inventories
- Risk Analysis: Calculate and track security risk metrics
Best Practices
- API Key Usage: Use NVD API key for higher rate limits
- Caching: Cache downloaded data to reduce API calls
- Incremental Updates: Download only new/changed data
- Error Handling: Handle network and API errors gracefully
- Rate Limiting: Respect NVD API rate limits
Performance Optimization
- Batch Processing: Process multiple CPEs together
- Parallel Downloads: Use concurrent downloads for large datasets
- Local Storage: Store frequently accessed data locally
- Compression: Compress cached data to save space
Security Considerations
- Data Validation: Validate downloaded data integrity
- Secure Storage: Protect cached vulnerability data
- Access Control: Limit access to sensitive vulnerability information
- Update Verification: Verify update authenticity
Next Steps
- Learn about CVE Mapping for detailed vulnerability correlation
- Explore Storage for persisting NVD data
- Check out Advanced Matching for sophisticated vulnerability detection