Registry
The Registry
provides a centralized collection for managing CWE entries. It offers storage, retrieval, hierarchy building, and import/export functionality.
Registry
type Registry struct {
Entries map[string]*CWE // CWE entries indexed by ID
Root *CWE // Root node of the hierarchy
}
The Registry is thread-safe for read operations but requires external synchronization for modifications.
Constructor
NewRegistry
func NewRegistry() *Registry
Creates a new empty registry.
Example:
registry := cwe.NewRegistry()
Core Operations
Register
func (r *Registry) Register(cwe *CWE) error
Adds a CWE to the registry.
Parameters:
cwe
- CWE instance to register
Returns:
error
- Error if CWE is nil, has no ID, or ID already exists
Example:
registry := cwe.NewRegistry()
xss := cwe.NewCWE("CWE-79", "Cross-site Scripting")
err := registry.Register(xss)
if err != nil {
log.Fatalf("Failed to register CWE: %v", err)
}
GetByID
func (r *Registry) GetByID(id string) (*CWE, bool)
Retrieves a CWE by its ID.
Parameters:
id
- CWE ID to look up
Returns:
*CWE
- The CWE instance if foundbool
- True if CWE was found
Example:
cwe, exists := registry.GetByID("CWE-79")
if exists {
fmt.Printf("Found: %s - %s\n", cwe.ID, cwe.Name)
} else {
fmt.Println("CWE not found")
}
GetAll
func (r *Registry) GetAll() map[string]*CWE
Returns all CWEs in the registry.
Returns:
map[string]*CWE
- Copy of the entries map
Count
func (r *Registry) Count() int
Returns the number of CWEs in the registry.
Example:
fmt.Printf("Registry contains %d CWEs\n", registry.Count())
Hierarchy Operations
BuildHierarchy
func (r *Registry) BuildHierarchy() error
Builds parent-child relationships between CWEs in the registry and identifies the root node.
Returns:
error
- Error if hierarchy building fails
Example:
// Add CWEs to registry
registry.Register(cwe.NewCWE("CWE-1000", "Research View"))
registry.Register(cwe.NewCWE("CWE-74", "Injection"))
registry.Register(cwe.NewCWE("CWE-79", "XSS"))
// Build hierarchy
err := registry.BuildHierarchy()
if err != nil {
log.Fatalf("Failed to build hierarchy: %v", err)
}
if registry.Root != nil {
fmt.Printf("Root: %s\n", registry.Root.ID)
}
GetRoots
func (r *Registry) GetRoots() []*CWE
Returns all CWEs that have no parent (potential root nodes).
Returns:
[]*CWE
- Slice of root CWEs
GetLeaves
func (r *Registry) GetLeaves() []*CWE
Returns all CWEs that have no children (leaf nodes).
Returns:
[]*CWE
- Slice of leaf CWEs
Search Operations
SearchByName
func (r *Registry) SearchByName(query string) []*CWE
Searches for CWEs by name (case-insensitive substring match).
Parameters:
query
- Search query string
Returns:
[]*CWE
- Slice of matching CWEs
Example:
results := registry.SearchByName("injection")
fmt.Printf("Found %d CWEs matching 'injection':\n", len(results))
for _, cwe := range results {
fmt.Printf(" %s: %s\n", cwe.ID, cwe.Name)
}
SearchByDescription
func (r *Registry) SearchByDescription(query string) []*CWE
Searches for CWEs by description (case-insensitive substring match).
FilterBySeverity
func (r *Registry) FilterBySeverity(severity string) []*CWE
Filters CWEs by severity level.
Parameters:
severity
- Severity level to filter by
Returns:
[]*CWE
- Slice of CWEs with matching severity
Import/Export Operations
ExportToJSON
func (r *Registry) ExportToJSON() ([]byte, error)
Exports the registry to JSON format.
Returns:
[]byte
- JSON dataerror
- Serialization error
Example:
jsonData, err := registry.ExportToJSON()
if err != nil {
log.Fatalf("Export failed: %v", err)
}
// Save to file
err = ioutil.WriteFile("cwe_data.json", jsonData, 0644)
if err != nil {
log.Fatalf("Failed to save file: %v", err)
}
ImportFromJSON
func (r *Registry) ImportFromJSON(data []byte) error
Imports CWEs from JSON data.
Parameters:
data
- JSON data to import
Returns:
error
- Import or parsing error
Example:
// Read from file
jsonData, err := ioutil.ReadFile("cwe_data.json")
if err != nil {
log.Fatalf("Failed to read file: %v", err)
}
// Import into registry
registry := cwe.NewRegistry()
err = registry.ImportFromJSON(jsonData)
if err != nil {
log.Fatalf("Import failed: %v", err)
}
fmt.Printf("Imported %d CWEs\n", registry.Count())
Statistics and Analysis
GetStatistics
func (r *Registry) GetStatistics() map[string]interface{}
Returns statistical information about the registry.
Returns:
map[string]interface{}
- Statistics map
Example:
stats := registry.GetStatistics()
fmt.Printf("Registry Statistics:\n")
fmt.Printf(" Total CWEs: %v\n", stats["total"])
fmt.Printf(" Root nodes: %v\n", stats["roots"])
fmt.Printf(" Leaf nodes: %v\n", stats["leaves"])
fmt.Printf(" Max depth: %v\n", stats["max_depth"])
Usage Examples
Basic Registry Operations
// Create registry
registry := cwe.NewRegistry()
// Add CWEs
cweList := []*cwe.CWE{
cwe.NewCWE("CWE-79", "Cross-site Scripting"),
cwe.NewCWE("CWE-89", "SQL Injection"),
cwe.NewCWE("CWE-287", "Improper Authentication"),
}
for _, c := range cweList {
err := registry.Register(c)
if err != nil {
log.Printf("Failed to register %s: %v", c.ID, err)
}
}
fmt.Printf("Registered %d CWEs\n", registry.Count())
// Retrieve CWE
if xss, exists := registry.GetByID("CWE-79"); exists {
fmt.Printf("Found XSS: %s\n", xss.Name)
}
Building and Exploring Hierarchies
// Create a simple hierarchy
registry := cwe.NewRegistry()
root := cwe.NewCWE("CWE-1000", "Research View")
injection := cwe.NewCWE("CWE-74", "Injection")
xss := cwe.NewCWE("CWE-79", "Cross-site Scripting")
sqli := cwe.NewCWE("CWE-89", "SQL Injection")
// Register all CWEs
registry.Register(root)
registry.Register(injection)
registry.Register(xss)
registry.Register(sqli)
// Build relationships manually
root.AddChild(injection)
injection.AddChild(xss)
injection.AddChild(sqli)
// Build registry hierarchy
err := registry.BuildHierarchy()
if err != nil {
log.Fatal(err)
}
// Explore hierarchy
fmt.Printf("Root: %s\n", registry.Root.ID)
fmt.Printf("Roots: %d\n", len(registry.GetRoots()))
fmt.Printf("Leaves: %d\n", len(registry.GetLeaves()))
Search and Filter Operations
// Search by name
injectionCWEs := registry.SearchByName("injection")
fmt.Printf("CWEs with 'injection' in name: %d\n", len(injectionCWEs))
// Search by description
scriptCWEs := registry.SearchByDescription("script")
fmt.Printf("CWEs with 'script' in description: %d\n", len(scriptCWEs))
// Filter by severity
highSeverityCWEs := registry.FilterBySeverity("High")
fmt.Printf("High severity CWEs: %d\n", len(highSeverityCWEs))
Data Persistence
// Export registry
jsonData, err := registry.ExportToJSON()
if err != nil {
log.Fatal(err)
}
// Save to file
err = ioutil.WriteFile("my_cwe_collection.json", jsonData, 0644)
if err != nil {
log.Fatal(err)
}
// Later, load from file
newRegistry := cwe.NewRegistry()
savedData, err := ioutil.ReadFile("my_cwe_collection.json")
if err != nil {
log.Fatal(err)
}
err = newRegistry.ImportFromJSON(savedData)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Loaded %d CWEs from file\n", newRegistry.Count())
Working with DataFetcher
// Use DataFetcher to populate registry
fetcher := cwe.NewDataFetcher()
// Fetch multiple CWEs
ids := []string{"79", "89", "287", "22", "78"}
registry, err := fetcher.FetchMultiple(ids)
if err != nil {
log.Fatal(err)
}
// Registry is now populated
fmt.Printf("Fetched %d CWEs\n", registry.Count())
// Search within fetched data
results := registry.SearchByName("injection")
fmt.Printf("Found %d injection-related CWEs\n", len(results))
// Export for later use
jsonData, _ := registry.ExportToJSON()
ioutil.WriteFile("fetched_cwes.json", jsonData, 0644)
Thread Safety
- Read Operations: Thread-safe (GetByID, GetAll, Search methods)
- Write Operations: Not thread-safe (Register, BuildHierarchy)
- Concurrent Access: Use external synchronization for modifications
Performance Considerations
- Memory Usage: Stores all CWEs in memory
- Search Performance: Linear search for name/description queries
- Hierarchy Building: O(n²) complexity for relationship building
- Large Collections: Consider pagination for very large datasets