CVE Impact
{% if mode == 'dossier' %} Per-CVE deep-dive across the portfolio {% else %} Portfolio-wide CVE distribution + top exposures {% endif %}
Severity Distribution
{% if render_mode == 'fragment' and not fragment_scripts_enabled %}Top CVEs by Project Count
{% if render_mode == 'fragment' and not fragment_scripts_enabled %}CVE Detail
{% if render_mode != 'fragment' %} {% endif %} {# The pre-migration template at cve_impact.html:216-247 iterates `table_data.rows` (NOT `main` directly) and accesses cells via row.get('CVE ID', '') etc. with the exact TITLE-CASE column names from _CSV_COLUMNS at cve_impact.py:374-394. The migrated template preserves that contract. #} {% if table_data and table_data.rows %}| CVE ID | Severity | CVSS | Projects | KEV | EPSS | Exploits | Components |
|---|---|---|---|---|---|---|---|
| {{ row.get('CVE ID', '') }} | {{ row.get('Severity', 'UNKNOWN') }} | {{ "%.1f"|format(row.get('CVSS', 0)) }} | {{ row.get('Affected Projects', 0) }} | {% if row.get('KEV') %}KEV{% endif %} | {{ "%.1f"|format(row.get('EPSS Percentile', 0) * 100) }}% | {% if row.get('Exploits', 0) > 0 %}{{ row.get('Exploits', 0) }}{% endif %} | {{ row.get('Components', '')[:60] }}{% if row.get('Components', '')|length > 60 %}…{% endif %} |
No CVE data available.
{% endif %} {% else %} {# Dossier mode: per-CVE deep-dive blocks. Field names + DOM structure match the pre-migration template at cve_impact.html:251-420 — preserve all 11 sub-sections: header (NVD link + severity + CVSS + KEV/exploit chips), description, nvd_unavailable banner, meta items (CWE link + EPSS + first/last detected + attack vector + vuln_functions), known exploits table, AI prompt (--ai-prompts), AI remediation guidance dict (--ai), affected-projects table with entity-link deep-linking. project_details fields per cve_impact.py:706-719 (project_name, project_version, reachability_label, etc. — NOT project/version/reachability). #} {% for d in dossiers %} {% if d is mapping %}{{ d.cve_id }}
{{ d.severity or 'UNKNOWN' }} CVSS {{ "%.1f"|format(d.cvss|default(0)) }} {% if d.kev %}CISA KEV{% endif %} {% if d.has_exploit %}Known Exploit{% endif %}{{ d.description }}
{% elif d.title %}{{ d.title }}
{% endif %} {# nvd_unavailable warning banner #} {% if d.nvd_unavailable %}NVD data was unavailable for this CVE. Description and fix-version data may be incomplete. Check NVD directly.
{% endif %} {# Vulnerability metadata #} {# Known Exploits table #}Known Exploits
{% if d.exploit_details and d.exploit_details | length > 0 %}| Source | URL | Description | Maturity | Type |
|---|---|---|---|---|
| {{ exp.source }} | {% if exp.url %}{{ exp.url[:60] }}{% if exp.url|length > 60 %}…{% endif %}{% else %}—{% endif %} | {{ exp.description[:150] if exp.description else '—' }}{% if exp.description and exp.description|length > 150 %}…{% endif %} | {{ exp.maturity|default('—', true) }} | {{ exp.type|default('—', true) }} |
None known.
{% endif %} with Copy button #}
{% if d.ai_prompt %}
AI Prompt (click to expand, copy & paste into any LLM)
{% if render_mode != 'fragment' %}
{% endif %}
{{ d.ai_prompt }}
{% endif %}
{# AI Remediation Guidance (--ai) — STRUCTURED DICT, NOT a string.
Per cve_impact.py:998-1000 and pre-migration template at
cve_impact.html:352-371, ai_guidance has keys:
fix_version, guidance, workaround, code_search_hints,
project_notes (optional), confidence. #}
{% if d.ai_guidance %}
AI Remediation Guidance
Fix Version {{ d.ai_guidance.fix_version|default('—', true) }}
Guidance {{ d.ai_guidance.guidance|default('—', true) }}
Workaround {{ d.ai_guidance.workaround|default('—', true) }}
Code Search {{ d.ai_guidance.code_search_hints|default('—', true) }}
{% if d.ai_guidance.project_notes and d.ai_guidance.project_notes != '—' %}
Project Notes
{{ d.ai_guidance.project_notes }}
{% endif %}
Confidence {{ d.ai_guidance.confidence|default('—', true) }}
{% endif %}
{# Affected Projects — preserve domain-based entity deep-links.
project_details field names per cve_impact.py:706-719:
project_name, project_id, project_version,
project_version_id, component, component_id,
finding_internal_id, reachability_label,
triage_status, detected. #}
Affected Projects
Affects {{ d.affected_count }} project{{ 's' if d.affected_count != 1 else '' }}.
{% if d.reachable_count > 0 %}
Reachable in {{ d.reachable_count }}.
{% endif %}
{% if d.unreachable_count > 0 %}
Unreachable in {{ d.unreachable_count }}.
{% endif %}
{% if d.unknown_count > 0 %}
Inconclusive in {{ d.unknown_count }}.
{% endif %}
{% if d.project_details and d.project_details | length > 0 %}
Project
Version
Reachability
Component
Status
Detected
{% for p in d.project_details %}
{% if p is mapping %}
{% if domain and p.project_id and p.project_version_id and p.finding_internal_id %}{{ p.project_name }}{% elif domain and p.project_id %}{{ p.project_name }}{% else %}{{ p.project_name }}{% endif %}
{% if domain and p.project_id and p.project_version_id %}{{ p.project_version }}{% else %}{{ p.project_version }}{% endif %}
{{ p.reachability_label }}
{% if domain and p.project_id and p.project_version_id and p.component_id %}{{ p.component }}{% else %}{{ p.component }}{% endif %}
{{ p.triage_status|default('—') if p.triage_status else '—' }}
{{ p.detected[:10] if p.detected else '—' }}
{% endif %}
{% endfor %}
{% endif %}
No CVE data available for the selected filters.