vulnerability-management
Vulnerability lifecycle management including CVE tracking, CVSS scoring, risk prioritization, remediation workflows, and coordinated disclosure practices
Installation
Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.
View source ↗GuidesSkill instructions
Vulnerability Management
End-to-end vulnerability lifecycle from discovery through remediation and verification.
When to Use This Skill
Keywords: vulnerability management, CVE, CVSS, remediation, patching, risk prioritization, EPSS, KEV, vulnerability disclosure, bug bounty, patch management, vulnerability scanning, asset inventory
Use this skill when:
- Setting up vulnerability management programs
- Interpreting CVSS scores and metrics
- Prioritizing vulnerability remediation
- Designing patch management processes
- Implementing vulnerability disclosure programs
- Managing bug bounty programs
- Tracking CVE/CWE/NVD data
- Creating SLA policies for remediation
Quick Decision Tree
- Understanding vulnerability scores? → See CVSS Scoring
- Prioritizing what to fix first? → See Risk-Based Prioritization
- Designing remediation workflow? → See references/remediation-workflow.md
- Setting up disclosure program? → See Vulnerability Disclosure
- CVSS calculation details? → See references/cvss-scoring.md
Vulnerability Lifecycle
┌─────────────────────────────────────────────────────────────────┐
│ VULNERABILITY MANAGEMENT LIFECYCLE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ DISCOVER ──▶ ASSESS ──▶ PRIORITIZE ──▶ REMEDIATE ──▶ VERIFY │
│ │ │ │ │ │ │
│ ▼ ▼ ▼ ▼ ▼ │
│ ┌───────┐ ┌───────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │Scanner│ │CVSS │ │Risk │ │Patch/ │ │Rescan/ │ │
│ │Pentest│ │Context│ │Matrix │ │Config │ │Validate│ │
│ │Bug │ │Assets │ │EPSS+KEV│ │Mitigate│ │Close │ │
│ │Bounty │ │Impact │ │SLA │ │Accept │ │ │ │
│ └───────┘ └───────┘ └────────┘ └────────┘ └────────┘ │
│ │
│ CONTINUOUS: Monitor ◀──────────────────────────────────────────┤
│ │
└─────────────────────────────────────────────────────────────────┘
CVSS Scoring Overview
Common Vulnerability Scoring System provides standardized severity ratings.
CVSS v3.1 Score Ranges
| Score | Severity | Typical SLA |
|---|---|---|
| 9.0-10.0 | Critical | 24-72 hours |
| 7.0-8.9 | High | 7-14 days |
| 4.0-6.9 | Medium | 30-60 days |
| 0.1-3.9 | Low | 90-180 days |
| 0.0 | None | Risk acceptance |
CVSS v3.1 Metric Groups
public enum AttackVector { Network, Adjacent, Local, Physical }
public enum AttackComplexity { Low, High }
public enum PrivilegesRequired { None, Low, High }
public enum UserInteraction { None, Required }
public enum Scope { Unchanged, Changed }
public enum ImpactLevel { None, Low, High }
/// <summary>
/// CVSS v3.1 Base Score vector
/// </summary>
public sealed record CvssV31Vector(
AttackVector AttackVector,
AttackComplexity AttackComplexity,
PrivilegesRequired PrivilegesRequired,
UserInteraction UserInteraction,
Scope Scope,
ImpactLevel Confidentiality,
ImpactLevel Integrity,
ImpactLevel Availability)
{
private static readonly FrozenDictionary<AttackVector, (string Code, double Value)> AvMetrics =
new Dictionary<AttackVector, (string, double)>
{
[AttackVector.Network] = ("N", 0.85),
[AttackVector.Adjacent] = ("A", 0.62),
[AttackVector.Local] = ("L", 0.55),
[AttackVector.Physical] = ("P", 0.20)
}.ToFrozenDictionary();
private static readonly FrozenDictionary<AttackComplexity, (string Code, double Value)> AcMetrics =
new Dictionary<AttackComplexity, (string, double)>
{
[AttackComplexity.Low] = ("L", 0.77),
[AttackComplexity.High] = ("H", 0.44)
}.ToFrozenDictionary();
private static readonly FrozenDictionary<ImpactLevel, (string Code, double Value)> ImpactMetrics =
new Dictionary<ImpactLevel, (string, double)>
{
[ImpactLevel.None] = ("N", 0.00),
[ImpactLevel.Low] = ("L", 0.22),
[ImpactLevel.High] = ("H", 0.56)
}.ToFrozenDictionary();
public string ToVectorString() =>
$"CVSS:3.1/AV:{AvMetrics[AttackVector].Code}/" +
$"AC:{AcMetrics[AttackComplexity].Code}/" +
$"PR:{GetPrCode()}/" +
$"UI:{(UserInteraction == UserInteraction.None ? "N" : "R")}/" +
$"S:{(Scope == Scope.Unchanged ? "U" : "C")}/" +
$"C:{ImpactMetrics[Confidentiality].Code}/" +
$"I:{ImpactMetrics[Integrity].Code}/" +
$"A:{ImpactMetrics[Availability].Code}";
public double CalculateBaseScore()
{
// Impact sub-score
var iscBase = 1 - (
(1 - ImpactMetrics[Confidentiality].Value) *
(1 - ImpactMetrics[Integrity].Value) *
(1 - ImpactMetrics[Availability].Value));
var impact = Scope == Scope.Unchanged
? 6.42 * iscBase
: 7.52 * (iscBase - 0.029) - 3.25 * Math.Pow(iscBase - 0.02, 15);
// Exploitability sub-score
var exploitability = 8.22 *
AvMetrics[AttackVector].Value *
AcMetrics[AttackComplexity].Value *
GetPrValue() *
(UserInteraction == UserInteraction.None ? 0.85 : 0.62);
if (impact <= 0) return 0.0;
var score = Scope == Scope.Unchanged
? Math.Min(impact + exploitability, 10)
: Math.Min(1.08 * (impact + exploitability), 10);
return Math.Round(score * 10) / 10; // Round to 1 decimal
}
private string GetPrCode() => PrivilegesRequired switch
{
PrivilegesRequired.None => "N",
PrivilegesRequired.Low => "L",
PrivilegesRequired.High => "H",
_ => "N"
};
private double GetPrValue() => (PrivilegesRequired, Scope) switch
{
(PrivilegesRequired.None, _) => 0.85,
(PrivilegesRequired.Low, Scope.Unchanged) => 0.62,
(PrivilegesRequired.Low, Scope.Changed) => 0.68,
(PrivilegesRequired.High, Scope.Unchanged) => 0.27,
(PrivilegesRequired.High, Scope.Changed) => 0.50,
_ => 0.85
};
}
// Example: Log4Shell (CVE-2021-44228)
var log4shell = new CvssV31Vector(
AttackVector: AttackVector.Network,
AttackComplexity: AttackComplexity.Low,
PrivilegesRequired: PrivilegesRequired.None,
UserInteraction: UserInteraction.None,
Scope: Scope.Changed,
Confidentiality: ImpactLevel.High,
Integrity: ImpactLevel.High,
Availability: ImpactLevel.High);
Console.WriteLine($"Vector: {log4shell.ToVectorString()}");
Console.WriteLine($"Score: {log4shell.CalculateBaseScore()}"); // 10.0
For detailed CVSS scoring including Temporal and Environmental metrics, see references/cvss-scoring.md.
Risk-Based Prioritization
CVSS alone is insufficient for prioritization. Use multiple signals:
Prioritization Framework
using System.Collections.Frozen;
public enum AssetCriticality { Low, Medium, High, Critical }
public enum AssetExposure { Internal, Dmz, External }
public enum DataSensitivity { Public, Internal, Confidential, Restricted }
public enum ExploitMaturity { Unproven, Poc, Functional, High }
/// <summary>Complete context for vulnerability prioritization</summary>
public sealed record VulnerabilityContext(
string CveId,
double CvssBase,
double? CvssEnvironmental = null,
double? CvssTemporal = null,
double EpssProbability = 0.0, // 0-1 probability of exploitation
double EpssPercentile = 0.0, // Relative ranking
bool InKev = false,
DateTimeOffset? KevDueDate = null,
AssetCriticality AssetCriticality = AssetCriticality.Medium,
AssetExposure AssetExposure = AssetExposure.Internal,
DataSensitivity DataSensitivity = DataSensitivity.Internal,
bool PublicExploit = false,
ExploitMaturity ExploitMaturity = ExploitMaturity.Unproven);
public sealed record PriorityResult(double Score, string Category, int SlaHours);
/// <summary>Multi-factor vulnerability prioritization</summary>
public sealed class RiskPrioritizer
{
// Weights for different factors (tune based on org priorities)
private static readonly FrozenDictionary<string, double> Weights =
new Dictionary<string, double>
{
["cvss"] = 0.25,
["epss"] = 0.20,
["kev"] = 0.20,
["asset"] = 0.20,
["exploit"] = 0.15
}.ToFrozenDictionary();
private static readonly FrozenDictionary<AssetCriticality, double> AssetScores =
new Dictionary<AssetCriticality, double>
{
[AssetCriticality.Low] = 25,
[AssetCriticality.Medium] = 50,
[AssetCriticality.High] = 75,
[AssetCriticality.Critical] = 100
}.ToFrozenDictionary();
private static readonly FrozenDictionary<AssetExposure, double> ExposureMultipliers =
new Dictionary<AssetExposure, double>
{
[AssetExposure.Internal] = 0.7,
[AssetExposure.Dmz] = 0.85,
[AssetExposure.External] = 1.0
}.ToFrozenDictionary();
private static readonly FrozenDictionary<DataSensitivity, double> DataMultipliers =
new Dictionary<DataSensitivity, double>
{
[DataSensitivity.Public] = 0.5,
[DataSensitivity.Internal] = 0.7,
[DataSensitivity.Confidential] = 0.9,
[DataSensitivity.Restricted] = 1.0
}.ToFrozenDictionary();
private static readonly FrozenDictionary<ExploitMaturity, double> ExploitScores =
new Dictionary<ExploitMaturity, double>
{
[ExploitMaturity.Unproven] = 20,
[ExploitMaturity.Poc] = 50,
[ExploitMaturity.Functional] = 80,
[ExploitMaturity.High] = 100
}.ToFrozenDictionary();
/// <summary>Calculate composite priority score (0-100)</summary>
public double CalculatePriorityScore(VulnerabilityContext vuln)
{
// CVSS component (0-10 normalized to 0-100)
var cvssScore = (vuln.CvssEnvironmental ?? vuln.CvssTemporal ?? vuln.CvssBase) * 10;
// EPSS component (probability * 100)
var epssScore = vuln.EpssProbability * 100;
// KEV component (binary with boost)
var kevScore = vuln.InKev ? 100.0 : 0.0;
// Asset criticality component
var assetScore = AssetScores[vuln.AssetCriticality]
* ExposureMultipliers[vuln.AssetExposure]
* DataMultipliers[vuln.DataSensitivity];
// Exploit maturity component
var exploitScore = ExploitScores[vuln.ExploitMaturity];
if (vuln.PublicExploit)
exploitScore = Math.Max(exploitScore, 60);
// Weighted composite
var priority =
Weights["cvss"] * cvssScore +
Weights["epss"] * epssScore +
Weights["kev"] * kevScore +
Weights["asset"] * assetScore +
Weights["exploit"] * exploitScore;
return Math.Round(priority, 1);
}
/// <summary>Categorize priority score</summary>
public static string GetPriorityCategory(double score) => score switch
{
>= 80 => "P1 - Critical",
>= 60 => "P2 - High",
>= 40 => "P3 - Medium",
_ => "P4 - Low"
};
/// <summary>Get remediation SLA in hours</summary>
public static int GetSlaHours(double score) => score switch
{
>= 80 => 24,
>= 60 => 168, // 7 days
>= 40 => 720, // 30 days
_ => 2160 // 90 days
};
/// <summary>Calculate complete priority result</summary>
public PriorityResult Evaluate(VulnerabilityContext vuln)
{
var score = CalculatePriorityScore(vuln);
return new PriorityResult(score, GetPriorityCategory(score), GetSlaHours(score));
}
}
// Example usage
var vuln = new VulnerabilityContext(
CveId: "CVE-2021-44228",
CvssBase: 10.0,
EpssProbability: 0.975,
EpssPercentile: 0.999,
InKev: true,
AssetCriticality: AssetCriticality.Critical,
AssetExposure: AssetExposure.External,
DataSensitivity: DataSensitivity.Confidential,
PublicExploit: true,
ExploitMaturity: ExploitMaturity.High);
var prioritizer = new RiskPrioritizer();
var result = prioritizer.Evaluate(vuln);
Console.WriteLine($"Priority Score: {result.Score}"); // ~95
Console.WriteLine($"Category: {result.Category}"); // P1 - Critical
Console.WriteLine($"SLA: {result.SlaHours} hours"); // 24
EPSS Integration
using System.Net.Http.Json;
using System.Text.Json.Serialization;
public sealed record EpssScore(
string Cve,
double Epss,
double Percentile,
string Date);
/// <summary>Client for EPSS (Exploit Prediction Scoring System) API</summary>
public sealed class EpssClient(HttpClient httpClient)
{
private const string BaseUrl = "https://api.first.org/data/v1/epss";
/// <summary>Get EPSS score for a CVE</summary>
public async Task<EpssScore?> GetScoreAsync(string cveId, CancellationToken ct = default)
{
var response = await httpClient.GetFromJsonAsync<EpssResponse>(
$"{BaseUrl}?cve={Uri.EscapeDataString(cveId)}", ct);
if (response?.Data is not { Count: > 0 })
return null;
var data = response.Data[0];
return new EpssScore(data.Cve, data.Epss, data.Percentile, data.Date);
}
/// <summary>Get EPSS scores for multiple CVEs</summary>
public async Task<IReadOnlyList<EpssScore>> GetBulkScoresAsync(
IEnumerable<string> cveIds,
CancellationToken ct = default)
{
var cveParam = string.Join(",", cveIds.Select(Uri.EscapeDataString));
var response = await httpClient.GetFromJsonAsync<EpssResponse>(
$"{BaseUrl}?cve={cveParam}", ct);
return response?.Data?
.Select(d => new EpssScore(d.Cve, d.Epss, d.Percentile, d.Date))
.ToArray() ?? [];
}
private sealed record EpssResponse(
[property: JsonPropertyName("data")] List<EpssData>? Data);
private sealed record EpssData(
[property: JsonPropertyName("cve")] string Cve,
[property: JsonPropertyName("epss")] double Epss,
[property: JsonPropertyName("percentile")] double Percentile,
[property: JsonPropertyName("date")] string Date);
}
// Registration with IHttpClientFactory
// services.AddHttpClient<EpssClient>();
KEV (Known Exploited Vulnerabilities) Integration
using System.Collections.Concurrent;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
/// <summary>CISA Known Exploited Vulnerability entry</summary>
public sealed record KevEntry(
string CveId,
string VendorProject,
string Product,
string VulnerabilityName,
DateOnly DateAdded,
DateOnly DueDate,
string ShortDescription,
string RequiredAction,
string Notes);
/// <summary>Client for CISA KEV catalog</summary>
public sealed class KevClient(HttpClient httpClient)
{
private const string CatalogUrl =
"https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json";
private readonly ConcurrentDictionary<string, KevEntry> _cache = new();
private DateTimeOffset _lastRefresh = DateTimeOffset.MinValue;
public DateTimeOffset LastRefresh => _lastRefresh;
/// <summary>Refresh KEV catalog from CISA</summary>
public async Task RefreshCatalogAsync(CancellationToken ct = default)
{
var catalog = await httpClient.GetFromJsonAsync<KevCatalog>(CatalogUrl, ct)
?? throw new InvalidOperationException("Failed to fetch KEV catalog");
_cache.Clear();
foreach (var vuln in catalog.Vulnerabilities ?? [])
{
var entry = new KevEntry(
CveId: vuln.CveId,
VendorProject: vuln.VendorProject,
Product: vuln.Product,
VulnerabilityName: vuln.VulnerabilityName,
DateAdded: DateOnly.Parse(vuln.DateAdded),
DueDate: DateOnly.Parse(vuln.DueDate),
ShortDescription: vuln.ShortDescription,
RequiredAction: vuln.RequiredAction,
Notes: vuln.Notes ?? string.Empty);
_cache[entry.CveId] = entry;
}
_lastRefresh = DateTimeOffset.UtcNow;
}
/// <summary>Check if CVE is in KEV catalog</summary>
public bool IsInKev(string cveId) => _cache.ContainsKey(cveId);
/// <summary>Get KEV entry for CVE</summary>
public KevEntry? GetEntry(string cveId) =>
_cache.TryGetValue(cveId, out var entry) ? entry : null;
/// <summary>Get all overdue KEV entries</summary>
public IReadOnlyList<KevEntry> GetOverdue()
{
var today = DateOnly.FromDateTime(DateTime.UtcNow);
return _cache.Values.Where(e => e.DueDate < today).ToArray();
}
private sealed record KevCatalog(
[property: JsonPropertyName("vulnerabilities")] List<KevVuln>? Vulnerabilities);
private sealed record KevVuln(
[property: JsonPropertyName("cveID")] string CveId,
[property: JsonPropertyName("vendorProject")] string VendorProject,
[property: JsonPropertyName("product")] string Product,
[property: JsonPropertyName("vulnerabilityName")] string VulnerabilityName,
[property: JsonPropertyName("dateAdded")] string DateAdded,
[property: JsonPropertyName("dueDate")] string DueDate,
[property: JsonPropertyName("shortDescription")] string ShortDescription,
[property: JsonPropertyName("requiredAction")] string RequiredAction,
[property: JsonPropertyName("notes")] string? Notes);
}
// Registration with IHttpClientFactory
// services.AddHttpClient<KevClient>();
Vulnerability Disclosure
Security.txt
# security.txt - RFC 9116 compliant
# Place at /.well-known/security.txt
Contact: mailto:security@example.com
Contact: https://example.com/security/report
Expires: 2025-12-31T23:59:59.000Z
Encryption: https://example.com/.well-known/pgp-key.txt
Acknowledgments: https://example.com/security/hall-of-fame
Preferred-Languages: en
Canonical: https://example.com/.well-known/security.txt
Policy: https://example.com/security/policy
Hiring: https://example.com/careers/security
Disclosure Policy
# Vulnerability Disclosure Policy
## Scope
The following assets are in scope:
- *.example.com
- Example Mobile Apps (iOS, Android)
- Example API (api.example.com)
Out of scope:
- Third-party services
- Social engineering attacks
- Physical security testing
- Denial of service attacks
## Rules of Engagement
- Do not access or modify data belonging to others
- Stop testing and report immediately if you access user data
- Do not publicly disclose before we've addressed the issue
- Provide sufficient detail to reproduce the issue
## Safe Harbor
We will not pursue legal action against researchers who:
- Act in good faith
- Avoid privacy violations
- Do not cause service disruption
- Follow responsible disclosure timeline
## Timeline
- Acknowledgment: 3 business days
- Initial assessment: 7 business days
- Status updates: Every 14 days
- Resolution target: 90 days (varies by severity)
## Rewards
| Severity | Bounty Range |
|----------|--------------|
| Critical | $5,000 - $25,000 |
| High | $2,000 - $5,000 |
| Medium | $500 - $2,000 |
| Low | $100 - $500 |
Bug Bounty Integration
using System.Collections.Frozen;
public enum ReportStatus
{
New,
Triaged,
Duplicate,
Informative,
NotApplicable,
Resolved,
BountyAwarded
}
public enum BountySeverity { Critical, High, Medium, Low }
/// <summary>Bug bounty report tracking</summary>
public sealed record BountyReport(
string Id,
string Title,
string Reporter,
BountySeverity Severity,
ReportStatus Status,
DateTimeOffset SubmittedAt,
string Asset,
string Description,
string ReproductionSteps,
string Impact,
string? CveId = null,
decimal? BountyAmount = null,
DateTimeOffset? ResolvedAt = null);
public sealed record SlaComplianceResult(
int SlaHours,
double ElapsedHours,
bool IsCompliant,
double RemainingHours);
public sealed record DisclosureTimeline(
DateTimeOffset Submitted,
DateTimeOffset TriageDeadline,
DateTimeOffset InitialResponse,
DateTimeOffset ResolutionTarget,
DateTimeOffset PublicDisclosure);
/// <summary>Manage bug bounty program operations</summary>
public sealed class BugBountyManager
{
private static readonly FrozenDictionary<BountySeverity, (decimal Min, decimal Max)> SeverityBountyRange =
new Dictionary<BountySeverity, (decimal, decimal)>
{
[BountySeverity.Critical] = (5000, 25000),
[BountySeverity.High] = (2000, 5000),
[BountySeverity.Medium] = (500, 2000),
[BountySeverity.Low] = (100, 500)
}.ToFrozenDictionary();
private static readonly FrozenDictionary<BountySeverity, int> SlaHours =
new Dictionary<BountySeverity, int>
{
[BountySeverity.Critical] = 24,
[BountySeverity.High] = 72,
[BountySeverity.Medium] = 168,
[BountySeverity.Low] = 336
}.ToFrozenDictionary();
/// <summary>Calculate bounty amount based on severity and factors</summary>
public decimal CalculateBounty(
BountySeverity severity,
double impactFactor = 1.0,
double qualityFactor = 1.0)
{
var (minBounty, maxBounty) = SeverityBountyRange.GetValueOrDefault(severity);
// Base bounty is midpoint
var baseBounty = (minBounty + maxBounty) / 2;
// Apply factors
var adjusted = baseBounty * (decimal)impactFactor * (decimal)qualityFactor;
// Clamp to range
return Math.Clamp(adjusted, minBounty, maxBounty);
}
/// <summary>Check if report is within SLA</summary>
public SlaComplianceResult CheckSlaCompliance(BountyReport report)
{
var slaHours = SlaHours.GetValueOrDefault(report.Severity, 168);
var elapsed = (DateTimeOffset.UtcNow - report.SubmittedAt).TotalHours;
return new SlaComplianceResult(
SlaHours: slaHours,
ElapsedHours: elapsed,
IsCompliant: elapsed <= slaHours,
RemainingHours: Math.Max(0, slaHours - elapsed));
}
/// <summary>Generate coordinated disclosure timeline</summary>
public static DisclosureTimeline GenerateDisclosureTimeline(DateTimeOffset submitted) =>
new(
Submitted: submitted,
TriageDeadline: submitted.AddDays(3),
InitialResponse: submitted.AddDays(7),
ResolutionTarget: submitted.AddDays(90),
PublicDisclosure: submitted.AddDays(104)); // 90 + 14 days
}
SLA Configuration
# vulnerability-sla.yaml
sla_policy:
name: "Production Vulnerability SLA"
version: "2.0"
effective_date: "2024-01-01"
# Default SLAs by CVSS score
severity_slas:
critical: # CVSS 9.0-10.0
detection_to_triage: 4h
triage_to_remediation_start: 24h
remediation_sla: 72h
total_sla: 96h
escalation_path:
- level: 1
after: 24h
notify: [security-team, engineering-lead]
- level: 2
after: 48h
notify: [ciso, vp-engineering]
- level: 3
after: 72h
notify: [ceo, board]
high: # CVSS 7.0-8.9
detection_to_triage: 8h
triage_to_remediation_start: 48h
remediation_sla: 168h # 7 days
total_sla: 216h
escalation_path:
- level: 1
after: 72h
notify: [security-team]
- level: 2
after: 120h
notify: [ciso]
medium: # CVSS 4.0-6.9
detection_to_triage: 24h
triage_to_remediation_start: 168h
remediation_sla: 720h # 30 days
total_sla: 888h
escalation_path:
- level: 1
after: 336h
notify: [security-team]
low: # CVSS 0.1-3.9
detection_to_triage: 72h
triage_to_remediation_start: 336h
remediation_sla: 2160h # 90 days
total_sla: 2496h
escalation_path: []
# Overrides for specific conditions
overrides:
- condition: "in_kev == true"
override_sla: "critical"
reason: "CISA KEV mandates accelerated remediation"
- condition: "epss_percentile >= 0.95"
decrease_sla_percent: 50
reason: "High exploitation probability"
- condition: "asset_exposure == 'external' and asset_criticality == 'critical'"
override_sla: "critical"
reason: "Internet-facing critical assets"
# Risk acceptance policy
risk_acceptance:
allowed_severities: [low, medium]
max_acceptance_period: 180d
required_approvers:
low: [security-team-lead]
medium: [ciso]
documentation_required: true
review_frequency: 30d
Security Checklist
Before finalizing vulnerability management setup:
- Asset inventory complete and current
- Scanning coverage for all assets
- CVSS + EPSS + KEV prioritization configured
- SLAs defined and communicated
- Escalation paths established
- Remediation workflow documented
- Disclosure policy published (security.txt)
- Bug bounty program considered
- Metrics and reporting established
- Exception/risk acceptance process defined
References
- CVSS Scoring Deep Dive - v3.1 and v4.0 detailed calculation
- Remediation Workflow - End-to-end remediation processes
Version History
- v1.0.0 (2025-12-26): Initial release with CVSS, prioritization, disclosure
Last Updated: 2025-12-26
Examples
Read the usage examples in the source repository.
View source ↗Source history
- Indexed on
- 2026-01-20
- Index updated
- 2026-02-04
- Branch
- main
Index and sync dates describe this directory. View the source repository for code history.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!