microsoft/hve-core
Publicmirrored fromhttps://github.com/microsoft/hve-coreAvailable
scripts/security/Modules/SecurityClasses.psm1
149lines · modecode
| 1 | # Copyright (c) Microsoft Corporation. |
| 2 | # SPDX-License-Identifier: MIT |
| 3 | |
| 4 | # SecurityClasses.psm1 |
| 5 | # |
| 6 | # Purpose: Shared class definitions for security scanning scripts. |
| 7 | # Author: HVE Core Team |
| 8 | |
| 9 | <# |
| 10 | .SYNOPSIS |
| 11 | Shared class definitions for dependency pinning and compliance reporting. |
| 12 | |
| 13 | .DESCRIPTION |
| 14 | This module contains class definitions used by security scanning scripts: |
| 15 | - DependencyViolation: Represents a single dependency pinning violation |
| 16 | - ComplianceReport: Aggregates violations and generates compliance reports |
| 17 | |
| 18 | .NOTES |
| 19 | Classes must be imported using 'using module' syntax at the top of scripts: |
| 20 | using module ./Modules/SecurityClasses.psm1 |
| 21 | #> |
| 22 | |
| 23 | class DependencyViolation { |
| 24 | <# |
| 25 | .SYNOPSIS |
| 26 | Represents a single dependency pinning violation. |
| 27 | |
| 28 | .DESCRIPTION |
| 29 | Contains information about a dependency that is not properly pinned, |
| 30 | including file location, dependency details, and remediation guidance. |
| 31 | |
| 32 | ViolationType values: |
| 33 | - Unpinned: Dependency is not pinned to an immutable reference |
| 34 | - Stale: Pinned dependency has a newer version available |
| 35 | - VersionMismatch: Version comment does not match the resolved pinned reference |
| 36 | - MissingVersionComment: Dependency is pinned but lacks a human-readable version comment |
| 37 | - MissingPermissions: Workflow file lacks required permissions declarations |
| 38 | - Empty string: Default or unclassified violation |
| 39 | #> |
| 40 | |
| 41 | [string]$File |
| 42 | [int]$Line |
| 43 | [string]$Type |
| 44 | [string]$Name |
| 45 | [string]$Version |
| 46 | [string]$CurrentRef |
| 47 | [ValidateSet('High', 'Medium', 'Low', 'Info')] |
| 48 | [string]$Severity |
| 49 | [ValidateSet('Unpinned', 'Stale', 'VersionMismatch', 'MissingVersionComment', 'MissingPermissions', '')] |
| 50 | [string]$ViolationType |
| 51 | [string]$Description |
| 52 | [string]$Remediation |
| 53 | [hashtable]$Metadata |
| 54 | |
| 55 | DependencyViolation() { |
| 56 | $this.Metadata = @{} |
| 57 | } |
| 58 | |
| 59 | DependencyViolation( |
| 60 | [string]$File, |
| 61 | [int]$Line, |
| 62 | [string]$Type, |
| 63 | [string]$Name, |
| 64 | [string]$Severity, |
| 65 | [string]$Description |
| 66 | ) { |
| 67 | $this.File = $File |
| 68 | $this.Line = $Line |
| 69 | $this.Type = $Type |
| 70 | $this.Name = $Name |
| 71 | $this.Severity = $Severity |
| 72 | $this.Description = $Description |
| 73 | $this.Metadata = @{} |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | class ComplianceReport { |
| 78 | <# |
| 79 | .SYNOPSIS |
| 80 | Aggregates dependency violations and generates compliance reports. |
| 81 | |
| 82 | .DESCRIPTION |
| 83 | Collects violations from dependency scans and provides metrics like |
| 84 | compliance score, total dependencies, and summary by type. |
| 85 | #> |
| 86 | |
| 87 | [string]$ScanPath |
| 88 | [datetime]$Timestamp |
| 89 | [int]$TotalFiles |
| 90 | [int]$ScannedFiles |
| 91 | [int]$TotalDependencies |
| 92 | [int]$PinnedDependencies |
| 93 | [int]$UnpinnedDependencies |
| 94 | [decimal]$ComplianceScore |
| 95 | [DependencyViolation[]]$Violations |
| 96 | [hashtable]$Summary |
| 97 | [hashtable]$Metadata |
| 98 | |
| 99 | ComplianceReport() { |
| 100 | $this.Timestamp = Get-Date |
| 101 | $this.Violations = @() |
| 102 | $this.Summary = @{} |
| 103 | $this.Metadata = @{} |
| 104 | } |
| 105 | |
| 106 | ComplianceReport([string]$ScanPath) { |
| 107 | $this.ScanPath = $ScanPath |
| 108 | $this.Timestamp = Get-Date |
| 109 | $this.Violations = @() |
| 110 | $this.Summary = @{} |
| 111 | $this.Metadata = @{} |
| 112 | } |
| 113 | |
| 114 | [void] AddViolation([DependencyViolation]$Violation) { |
| 115 | $this.Violations += $Violation |
| 116 | $this.UnpinnedDependencies = $this.Violations.Count |
| 117 | } |
| 118 | |
| 119 | [void] CalculateScore() { |
| 120 | if ($this.TotalDependencies -gt 0) { |
| 121 | $this.ComplianceScore = [math]::Round( |
| 122 | ($this.PinnedDependencies / $this.TotalDependencies) * 100, 2 |
| 123 | ) |
| 124 | } |
| 125 | else { |
| 126 | $this.ComplianceScore = 100.0 |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | [hashtable] ToHashtable() { |
| 131 | return @{ |
| 132 | ScanPath = $this.ScanPath |
| 133 | Timestamp = $this.Timestamp.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') |
| 134 | TotalFiles = $this.TotalFiles |
| 135 | ScannedFiles = $this.ScannedFiles |
| 136 | TotalDependencies = $this.TotalDependencies |
| 137 | PinnedDependencies = $this.PinnedDependencies |
| 138 | UnpinnedDependencies = $this.UnpinnedDependencies |
| 139 | ComplianceScore = $this.ComplianceScore |
| 140 | Violations = $this.Violations |
| 141 | Summary = $this.Summary |
| 142 | Metadata = $this.Metadata |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | # Classes are exported automatically when imported via 'using module' syntax. |
| 148 | # No functions to export. |
| 149 | Export-ModuleMember -Function @() |
| 150 | |