Problem
When importing GitHub Security Advisories via mayu ingest --source ghsa --repo, the GitHub API returns a "severity": "critical" label field. However, ConvertGitHubToOSV() in internal/parser/github.go only processes CVSS vector strings and discards the severity label when no vector is available.
This causes:
- No severity displayed in the UI for advisories without CVSS vectors (e.g., GHSA-ff9f-jf42-662q)
vulnerability_summary.severity_worst/severity_best not populated from GHSA data
Root Cause
buildSeverity() only adds entries when cvss_severities.cvss_v4.vector_string, cvss_severities.cvss_v3.vector_string, or legacy cvss.vector_string is non-empty. The GitHubAdvisory.Severity string field ("critical", "high", "medium", "low") is completely ignored.
OSV schema only supports CVSS vectors in severity[], so label-only severity has no representation in the OSV format.
Proposed Solution
Short term
- In
buildSeverity(), when no CVSS vector is available but adv.Severity label exists, store it in database_specific.github_severity in the generated OSV JSON
- Update
vulnerability_summary computation to consider GHSA severity labels (normalize to 5-level scale)
Medium term (preferred)
- Add a
ghsa_entries table (similar to nvd_entries / mitre_entries) to store the full GitHub advisory data natively:
ghsa_entries {
BIGINT id PK
TEXT ghsa_id UK
TEXT vulnerability_id FK
TEXT severity_label
FLOAT8 cvss_v3_score
TEXT cvss_v3_vector
FLOAT8 cvss_v4_score
TEXT cvss_v4_vector
TEXT state
TEXT_ARRAY cwe_ids
TIMESTAMPTZ published_at
TIMESTAMPTZ updated_at
JSONB raw_json
}
- Continue generating OSV JSON for backward compatibility
- Use
ghsa_entries for vulnerability_summary severity calculation and UI detail display
- This follows the existing pattern where each data source has its own detail table
Context
References
Problem
When importing GitHub Security Advisories via
mayu ingest --source ghsa --repo, the GitHub API returns a"severity": "critical"label field. However,ConvertGitHubToOSV()ininternal/parser/github.goonly processes CVSS vector strings and discards the severity label when no vector is available.This causes:
vulnerability_summary.severity_worst/severity_bestnot populated from GHSA dataRoot Cause
buildSeverity()only adds entries whencvss_severities.cvss_v4.vector_string,cvss_severities.cvss_v3.vector_string, or legacycvss.vector_stringis non-empty. TheGitHubAdvisory.Severitystring field ("critical", "high", "medium", "low") is completely ignored.OSV schema only supports CVSS vectors in
severity[], so label-only severity has no representation in the OSV format.Proposed Solution
Short term
buildSeverity(), when no CVSS vector is available butadv.Severitylabel exists, store it indatabase_specific.github_severityin the generated OSV JSONvulnerability_summarycomputation to consider GHSA severity labels (normalize to 5-level scale)Medium term (preferred)
ghsa_entriestable (similar tonvd_entries/mitre_entries) to store the full GitHub advisory data natively:ghsa_entriesforvulnerability_summaryseverity calculation and UI detail displayContext
References
internal/parser/github.go—buildSeverity()functioninternal/store/summary.go— severity computation