mirror of
https://github.com/hanzoai/visor.git
synced 2026-09-24 17:04:14 +00:00
- Replace binary "Defended"/"Unmitigated" status with a richer `patched` field (tri-state: `PATCHED`, `EXTERNAL_MITIGATION_REQUIRED`, `UNPATCHED`). Required when `exploitable_under_gvisor` is true. - Chart: distinct yellow/orange/red bar segments per status. Legend shows percentages. - Chart: add a dashed "ghost" extrapolation on current-year bar projecting the expected year-end CVE count (suppressed when <2 months remain or projection within 15% of the actual count to avoid visual crowding). - Display entries without a CVE ID so chart and table counts are complete. - Add a CVSS chip, colored by score. - Render markdown-style backticks in descriptions as monospace, and wrap code identifiers throughout the data file in backticks. - Mobile: horizontally scrollable chart that starts scrolled to the most recent year; wrapped legend; fix stray divider border on stacked columns. - Preserve highlighted year in URL anchor. - Remove redundant "Vulnerability Overview & Impact" header and shorten "Target Ecosystem Scope" to "Scope".
394 lines
24 KiB
HTML
394 lines
24 KiB
HTML
---
|
|
title: Security Record
|
|
layout: base
|
|
permalink: /security-track-record/
|
|
---
|
|
|
|
<div class="container">
|
|
<div class="users-content">
|
|
<h1>gVisor Security Record</h1>
|
|
|
|
<style>
|
|
.year-chart-btn {
|
|
cursor: pointer;
|
|
padding: 12px 6px;
|
|
border-radius: 12px;
|
|
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
}
|
|
.year-chart-btn:hover {
|
|
background-color: #f8fafc;
|
|
}
|
|
.year-chart-btn .chart-bar-defended {
|
|
background-color: #94a3b8;
|
|
transition: all 0.25s ease;
|
|
}
|
|
.year-chart-btn .chart-bar-patched {
|
|
background-color: #cbd5e1;
|
|
transition: all 0.25s ease;
|
|
}
|
|
.year-chart-btn .chart-bar-mitigated {
|
|
background-color: #cbd5e1;
|
|
transition: all 0.25s ease;
|
|
}
|
|
.year-chart-btn .chart-bar-vulnerable {
|
|
background-color: #cbd5e1;
|
|
transition: all 0.25s ease;
|
|
}
|
|
.year-chart-btn:hover .chart-bar-defended {
|
|
background-color: #64748b;
|
|
}
|
|
.year-chart-btn:hover .chart-bar-patched {
|
|
background-color: #94a3b8;
|
|
}
|
|
.year-chart-btn:hover .chart-bar-mitigated {
|
|
background-color: #94a3b8;
|
|
}
|
|
.year-chart-btn:hover .chart-bar-vulnerable {
|
|
background-color: #94a3b8;
|
|
}
|
|
.year-chart-btn.active-chart-col {
|
|
background-color: #f0f6ff;
|
|
box-shadow: 0 4px 24px rgba(40, 111, 215, 0.12);
|
|
border: 1px solid #dbe8ff;
|
|
}
|
|
.year-chart-btn.active-chart-col .chart-bar-defended {
|
|
background-color: #286FD7;
|
|
box-shadow: 0 4px 12px rgba(40, 111, 215, 0.3);
|
|
}
|
|
.year-chart-btn.active-chart-col .chart-bar-patched {
|
|
background-color: #f4c430;
|
|
box-shadow: 0 4px 12px rgba(244, 196, 48, 0.3);
|
|
}
|
|
.year-chart-btn.active-chart-col .chart-bar-mitigated {
|
|
background-color: #ed7d31;
|
|
box-shadow: 0 4px 12px rgba(237, 125, 49, 0.3);
|
|
}
|
|
.year-chart-btn.active-chart-col .chart-bar-vulnerable {
|
|
background-color: #b91c1c;
|
|
box-shadow: 0 4px 12px rgba(185, 28, 28, 0.3);
|
|
}
|
|
.year-chart-btn.active-chart-col .chart-year-label {
|
|
color: #286FD7 !important;
|
|
font-weight: 700 !important;
|
|
}
|
|
.year-chart-btn .chart-count-label {
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
color: #64748b;
|
|
margin-bottom: 8px;
|
|
text-align: center;
|
|
transition: color 0.25s ease;
|
|
}
|
|
.year-chart-btn.active-chart-col .chart-count-label {
|
|
color: #1e293b;
|
|
font-weight: 700;
|
|
}
|
|
.cve-meta-col {
|
|
border-left: 1px solid #e5e5e5;
|
|
}
|
|
@media (max-width: 991px) {
|
|
/* The two detail columns stack vertically below Bootstrap's md breakpoint,
|
|
so the divider border-left would appear as a stray vertical line. */
|
|
.cve-meta-col {
|
|
border-left: none;
|
|
}
|
|
}
|
|
.cve-item code {
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
|
|
background-color: #f1f5f9;
|
|
color: #0f172a;
|
|
padding: 1px 5px;
|
|
border-radius: 4px;
|
|
font-size: 0.88em;
|
|
}
|
|
</style>
|
|
|
|
<div class="marketing-chart-card" style="background: #ffffff; border: 1px solid #e2e8f0; border-radius: 16px; box-shadow: 0 12px 36px rgba(0, 0, 0, 0.06); margin-top: 35px; margin-bottom: 45px; overflow: hidden;">
|
|
<div style="padding: 32px 32px 10px 32px;">
|
|
{% assign legend_cves = site.data['cve-track-record'].cves %}
|
|
{% assign total_defended = 0 %}
|
|
{% assign total_patched = 0 %}
|
|
{% assign total_mitigatable = 0 %}
|
|
{% assign total_vulnerable = 0 %}
|
|
{% for item in legend_cves %}
|
|
{% if item.exploitable_under_gvisor %}
|
|
{% if item.patched == "PATCHED" %}
|
|
{% assign total_patched = total_patched | plus: 1 %}
|
|
{% elsif item.patched == "EXTERNAL_MITIGATION_REQUIRED" %}
|
|
{% assign total_mitigatable = total_mitigatable | plus: 1 %}
|
|
{% else %}
|
|
{% assign total_vulnerable = total_vulnerable | plus: 1 %}
|
|
{% endif %}
|
|
{% else %}
|
|
{% assign total_defended = total_defended | plus: 1 %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% assign legend_total = legend_cves | size %}
|
|
{% assign pct_defended = total_defended | times: 100.0 | divided_by: legend_total | round %}
|
|
{% assign pct_patched = total_patched | times: 100.0 | divided_by: legend_total | round %}
|
|
{% assign pct_mitigatable = total_mitigatable | times: 100.0 | divided_by: legend_total | round %}
|
|
{% assign pct_vulnerable = total_vulnerable | times: 100.0 | divided_by: legend_total | round %}
|
|
<div style="display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start;">
|
|
<div>
|
|
<h3 style="font-size: 24px; font-weight: 700; color: #1a202c; margin: 0 0 8px 0;">Vulnerabilities Defended by Year</h3>
|
|
<p style="font-size: 15px; color: #64748b; margin: 0; max-width: 540px;">An overview of high-impact Linux kernel vulnerabilities mitigated by gVisor over time.</p>
|
|
</div>
|
|
<div style="display: flex; flex-wrap: wrap; row-gap: 6px; align-items: center; background: #f8fafc; padding: 8px 16px; border-radius: 20px; border: 1px solid #e2e8f0; margin-top: 10px;">
|
|
<div style="display: flex; align-items: center; margin-right: 16px;">
|
|
<span style="display: inline-block; width: 12px; height: 12px; border-radius: 3px; background-color: #286FD7; margin-right: 6px;"></span>
|
|
<span style="font-size: 13px; font-weight: 600; color: #334155;">Defended ({{ pct_defended }}%)</span>
|
|
</div>
|
|
<div style="display: flex; align-items: center; margin-right: 16px;">
|
|
<span style="display: inline-block; width: 12px; height: 12px; border-radius: 3px; background-color: #f4c430; margin-right: 6px;"></span>
|
|
<span style="font-size: 13px; font-weight: 600; color: #334155;">Patched ({{ pct_patched }}%)</span>
|
|
</div>
|
|
<div style="display: flex; align-items: center; margin-right: 16px;">
|
|
<span style="display: inline-block; width: 12px; height: 12px; border-radius: 3px; background-color: #ed7d31; margin-right: 6px;"></span>
|
|
<span style="font-size: 13px; font-weight: 600; color: #334155;">Mitigatable ({{ pct_mitigatable }}%)</span>
|
|
</div>
|
|
<div style="display: flex; align-items: center;">
|
|
<span style="display: inline-block; width: 12px; height: 12px; border-radius: 3px; background-color: #b91c1c; margin-right: 6px;"></span>
|
|
<span style="font-size: 13px; font-weight: 600; color: #334155;">Vulnerable ({{ pct_vulnerable }}%)</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div style="padding: 10px 32px 32px 32px;">
|
|
<div class="chart-container" style="display: flex; align-items: flex-end; justify-content: flex-start; height: 260px; padding: 32px 10px 10px 10px; overflow-x: auto; -webkit-overflow-scrolling: touch;">
|
|
{% assign valid_cves = site.data['cve-track-record'].cves %}
|
|
{% assign grouped_cves = valid_cves | group_by_exp: "item", "item.date | slice: 0, 4" %}
|
|
{% comment %} Current year + day-of-year (assuming 365-day years) for the ghost extrapolation. {% endcomment %}
|
|
{% assign current_year = site.time | date: "%Y" %}
|
|
{% assign day_of_year = site.time | date: "%j" | plus: 0 %}
|
|
{% assign max_cves = 1 %}
|
|
{% for group in grouped_cves %}
|
|
{% assign group_size = group.items | size %}
|
|
{% if group.name == current_year %}
|
|
{% assign group_projected = group_size | times: 365.0 | divided_by: day_of_year | round %}
|
|
{% assign group_days_remaining = 365 | minus: day_of_year %}
|
|
{% assign group_projected_scaled = group_projected | times: 100 %}
|
|
{% assign group_actual_threshold = group_size | times: 115 %}
|
|
{% comment %} Only let the projection drive the scale when it is shown: >= 2 months left and >= 15% above the actual count. {% endcomment %}
|
|
{% if group_projected_scaled >= group_actual_threshold and group_days_remaining >= 61 %}
|
|
{% assign group_size = group_projected %}
|
|
{% endif %}
|
|
{% endif %}
|
|
{% if group_size > max_cves %}
|
|
{% assign max_cves = group_size %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% assign max_cves_float = max_cves | times: 1.0 %}
|
|
{% for group in grouped_cves %}
|
|
{% assign total = group.items | size %}
|
|
{% assign saved_count = 0 %}
|
|
{% assign patched_count = 0 %}
|
|
{% assign mitigated_count = 0 %}
|
|
{% assign vulnerable_count = 0 %}
|
|
{% for item in group.items %}
|
|
{% if item.exploitable_under_gvisor %}
|
|
{% if item.patched == "PATCHED" %}
|
|
{% assign patched_count = patched_count | plus: 1 %}
|
|
{% elsif item.patched == "EXTERNAL_MITIGATION_REQUIRED" %}
|
|
{% assign mitigated_count = mitigated_count | plus: 1 %}
|
|
{% else %}
|
|
{% assign vulnerable_count = vulnerable_count | plus: 1 %}
|
|
{% endif %}
|
|
{% else %}
|
|
{% assign saved_count = saved_count | plus: 1 %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% assign total_percentage = total | times: 100.0 | divided_by: max_cves_float %}
|
|
{% assign is_current_year = false %}
|
|
{% assign projected = 0 %}
|
|
{% assign projected_percentage = 0 %}
|
|
{% if group.name == current_year %}
|
|
{% assign projected = total | times: 365.0 | divided_by: day_of_year | round %}
|
|
{% assign days_remaining = 365 | minus: day_of_year %}
|
|
{% assign projected_scaled = projected | times: 100 %}
|
|
{% assign actual_threshold = total | times: 115 %}
|
|
{% comment %} Suppress the extrapolation when the year is nearly over (< 2 months left) or the projection is within 15% of the actual count. {% endcomment %}
|
|
{% if projected_scaled >= actual_threshold and days_remaining >= 61 %}
|
|
{% assign is_current_year = true %}
|
|
{% assign projected_percentage = projected | times: 100.0 | divided_by: max_cves_float %}
|
|
{% endif %}
|
|
{% endif %}
|
|
{% assign saved_ratio = saved_count | times: 100.0 | divided_by: total %}
|
|
{% assign patched_ratio = patched_count | times: 100.0 | divided_by: total %}
|
|
{% assign mitigated_ratio = mitigated_count | times: 100.0 | divided_by: total %}
|
|
{% assign vulnerable_ratio = vulnerable_count | times: 100.0 | divided_by: total %}
|
|
<div class="chart-column year-chart-btn {% if forloop.last %}active-chart-col{% endif %}" data-year="{{ group.name }}" style="display: flex; flex-direction: column; justify-content: flex-end; align-items: center; flex-grow: 1; flex-shrink: 0; min-width: 52px; height: 100%; margin: 0 4px;">
|
|
<div class="chart-bar-area" style="position: relative; flex: 1 1 0%; min-height: 0; width: 100%; max-width: 48px; display: flex; flex-direction: column; justify-content: flex-end; align-items: stretch;">
|
|
{% if is_current_year %}
|
|
<div class="chart-ghost-bar" title="Projected total for {{ group.name }} at current pace" style="position: absolute; left: 0; right: 0; bottom: 0; height: {{ projected_percentage | at_most: 100 }}%; border: 2px dashed #cbd5e1; border-bottom: none; border-radius: 6px 6px 0 0; background-color: rgba(203, 213, 225, 0.08); z-index: 1; pointer-events: none;"></div>
|
|
<div class="chart-ghost-label" title="Extrapolated: projected total for {{ group.name }} at current pace" style="position: absolute; left: 0; right: 0; bottom: {{ projected_percentage | at_most: 100 }}%; margin-bottom: 4px; z-index: 1; pointer-events: auto; cursor: help; font-size: 12px; font-weight: 600; font-style: italic; color: #94a3b8; text-align: center; white-space: nowrap;">~{{ projected }}</div>
|
|
{% endif %}
|
|
<div class="chart-count-label" style="position: absolute; left: 0; right: 0; bottom: {{ total_percentage | at_most: 100 }}%; white-space: nowrap; z-index: 3;">{{ saved_count }}/{{ total }}</div>
|
|
<div class="chart-bar-wrapper" style="position: relative; z-index: 2; height: {{ total_percentage | at_most: 100 }}%; min-height: 6px; width: 100%; display: flex; flex-direction: column; justify-content: flex-end; border-radius: 6px 6px 0 0; box-shadow: 0 2px 4px rgba(0,0,0,0.06); overflow: hidden;">
|
|
<div class="chart-bar-vulnerable" style="height: {{ vulnerable_ratio }}%; width: 100%;"></div>
|
|
<div class="chart-bar-mitigated" style="height: {{ mitigated_ratio }}%; width: 100%;"></div>
|
|
<div class="chart-bar-patched" style="height: {{ patched_ratio }}%; width: 100%;"></div>
|
|
<div class="chart-bar-defended" style="height: {{ saved_ratio }}%; width: 100%;"></div>
|
|
</div>
|
|
</div>
|
|
<div class="chart-year-label" style="margin-top: 14px; font-weight: 600; font-size: 14px; color: #64748b; text-align: center; transition: color 0.25s ease;">{{ group.name }}</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const chartContainer = document.querySelector('.chart-container');
|
|
const chartBtns = document.querySelectorAll('.year-chart-btn');
|
|
|
|
// Horizontally scroll the chart so the given year's column is centered in view.
|
|
function centerChartOn(btn) {
|
|
if (!chartContainer || !btn) return;
|
|
const cRect = chartContainer.getBoundingClientRect();
|
|
const bRect = btn.getBoundingClientRect();
|
|
chartContainer.scrollLeft += (bRect.left - cRect.left) - (chartContainer.clientWidth / 2) + (bRect.width / 2);
|
|
}
|
|
|
|
// Highlight a year's chart column and show its CVE list. Returns true on success.
|
|
function activateYear(year) {
|
|
const btn = document.querySelector('.year-chart-btn[data-year="' + year + '"]');
|
|
if (!btn) return false;
|
|
chartBtns.forEach(b => b.classList.remove('active-chart-col'));
|
|
btn.classList.add('active-chart-col');
|
|
document.querySelectorAll('.tab-pane').forEach(pane => pane.classList.remove('active'));
|
|
const activePane = document.getElementById('year-' + year);
|
|
if (activePane) activePane.classList.add('active');
|
|
return true;
|
|
}
|
|
|
|
// Restore the highlighted year from the URL anchor (e.g. #2026), if present.
|
|
const hashYear = (window.location.hash || '').replace('#', '');
|
|
let restored = false;
|
|
if (/^\d{4}$/.test(hashYear) && activateYear(hashYear)) {
|
|
restored = true;
|
|
centerChartOn(document.querySelector('.year-chart-btn[data-year="' + hashYear + '"]'));
|
|
}
|
|
// Default: start scrolled all the way right so the most recent year is visible
|
|
// by default on narrow/mobile viewports.
|
|
if (!restored && chartContainer) {
|
|
chartContainer.scrollLeft = chartContainer.scrollWidth;
|
|
}
|
|
|
|
chartBtns.forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
const targetYear = this.getAttribute('data-year');
|
|
activateYear(targetYear);
|
|
|
|
// Preserve the highlighted year in the URL anchor (without jumping the page).
|
|
if (targetYear) {
|
|
history.replaceState(null, '', '#' + targetYear);
|
|
}
|
|
|
|
const header = document.getElementById('defense-database-header');
|
|
if (header) {
|
|
header.scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<h2 id="defense-database-header" style="margin-top: 40px;">Vulnerability Defense Database</h2>
|
|
<hr>
|
|
<p style="font-size: 16px; line-height: 1.6;">
|
|
This curated record is not a comprehensive list of all vulnerabilities, but focuses on high-impact CVEs relevant to production Kubernetes environments, specifically tracking critical threats highlighted in official <a href="https://docs.cloud.google.com/kubernetes-engine/security-bulletins" target="_blank" rel="noopener noreferrer">Google Kubernetes Engine (GKE) security bulletins</a>.
|
|
</p>
|
|
|
|
<!-- Nav tabs -->
|
|
<ul class="nav nav-tabs" role="tablist" style="display: none;">
|
|
{% for group in grouped_cves %}
|
|
<li role="presentation" {% if forloop.last %}class="active"{% endif %}>
|
|
<a href="#year-{{ group.name }}" aria-controls="year-{{ group.name }}" role="tab" data-toggle="tab" style="font-weight: 600;">{{ group.name }} <span class="badge" style="background-color: #666;">{{ group.items | size }}</span></a>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
|
|
<!-- Tab panes -->
|
|
<div class="tab-content" style="margin-top: 25px; margin-bottom: 60px;">
|
|
{% for group in grouped_cves %}
|
|
<div role="tabpanel" class="tab-pane {% if forloop.last %}active{% endif %}" id="year-{{ group.name }}">
|
|
<div class="panel-group" id="accordion-{{ group.name }}" role="tablist" aria-multiselectable="true">
|
|
{% assign quarter_groups = group.items | group_by_exp: "item", "item.date | slice: 5, 2 | plus: 2 | divided_by: 3 | prepend: 'Q'" %}
|
|
{% for q_group in quarter_groups %}
|
|
<div class="panel panel-default" style="border-radius: 4px; margin-bottom: 15px;">
|
|
<div class="panel-heading" role="tab" id="heading-{{ group.name }}-{{ q_group.name }}" style="padding: 15px 20px; background-color: #fff;">
|
|
<h4 class="panel-title" style="display: flex; justify-content: space-between; align-items: center;">
|
|
<a role="button" data-toggle="collapse" href="#collapse-{{ group.name }}-{{ q_group.name }}" aria-expanded="true" aria-controls="collapse-{{ group.name }}-{{ q_group.name }}" style="text-decoration: none; display: flex; align-items: center; flex-grow: 1;">
|
|
<span style="font-size: 18px; font-weight: bold; color: #333;">{{ q_group.name }} {{ group.name }}</span>
|
|
</a>
|
|
<span class="badge" style="background-color: #6c757d; padding: 6px 12px; font-size: 13px; border-radius: 12px; margin-left: 15px;">{{ q_group.items | size }} {% if q_group.items.size == 1 %}Vulnerability{% else %}Vulnerabilities{% endif %}</span>
|
|
</h4>
|
|
</div>
|
|
<div id="collapse-{{ group.name }}-{{ q_group.name }}" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="heading-{{ group.name }}-{{ q_group.name }}">
|
|
<div class="panel-body" style="background-color: #fcfcfc; padding: 25px 25px 5px 25px; border-top: 1px solid #eee;">
|
|
{% for item in q_group.items %}
|
|
<div class="cve-item" style="{% if forloop.last == false %}border-bottom: 1px solid #eee; margin-bottom: 20px; padding-bottom: 20px;{% else %}margin-bottom: 20px;{% endif %}">
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
|
|
<div style="display: flex; align-items: center;">
|
|
<span style="font-size: 18px; font-weight: 600; margin-right: 15px;">
|
|
{% if item.cve != nil and item.cve != '' %}
|
|
<a href="https://nvd.nist.gov/vuln/detail/{{ item.cve }}" target="_blank" rel="noopener noreferrer" style="color: #286FD7; text-decoration: none;">{{ item.cve }}</a>
|
|
{% else %}
|
|
<span style="color: #64748b;">No CVE assigned</span>
|
|
{% endif %}
|
|
</span>
|
|
{% if item.cvss != nil %}
|
|
{% comment %} CVSS chip: 11-color green→yellow→orange→red palette indexed by the rounded score (0-10), with a per-swatch readable text color. {% endcomment %}
|
|
{% assign cvss_index = item.cvss | round %}
|
|
{% if cvss_index < 0 %}{% assign cvss_index = 0 %}{% endif %}
|
|
{% if cvss_index > 10 %}{% assign cvss_index = 10 %}{% endif %}
|
|
{% assign cvss_bg_palette = "#2f6b4d,#3d8a5e,#82b481,#b9cf94,#d8e0a6,#eee9c2,#e8d3a2,#e0ad82,#d07a5e,#c0564d,#9c4a48" | split: "," %}
|
|
{% assign cvss_fg_palette = "#ffffff,#ffffff,#333333,#333333,#333333,#333333,#333333,#333333,#ffffff,#ffffff,#ffffff" | split: "," %}
|
|
<span class="label" title="CVSS: {{ item.cvss }}" style="background-color: {{ cvss_bg_palette[cvss_index] }}; color: {{ cvss_fg_palette[cvss_index] }}; padding: 2px 7px; font-size: 11px; font-weight: 600; border-radius: 10px;">{{ item.cvss }}</span>
|
|
{% endif %}
|
|
</div>
|
|
<div>
|
|
{% if item.exploitable_under_gvisor %}
|
|
{% if item.patched == "PATCHED" %}
|
|
<span class="label" style="background-color: #f4c430; color: #333; padding: 6px 12px; font-size: 13px; border-radius: 12px;">Patched</span>
|
|
{% elsif item.patched == "EXTERNAL_MITIGATION_REQUIRED" %}
|
|
<span class="label" style="background-color: #ed7d31; color: #fff; padding: 6px 12px; font-size: 13px; border-radius: 12px;">External mitigation required</span>
|
|
{% else %}
|
|
<span class="label" style="background-color: #b91c1c; color: #fff; padding: 6px 12px; font-size: 13px; border-radius: 12px;">Vulnerable</span>
|
|
{% endif %}
|
|
{% else %}
|
|
<span class="label label-success" style="padding: 6px 12px; font-size: 13px; border-radius: 12px;">Defended</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="row" style="font-size: 15px; line-height: 1.6;">
|
|
<div class="col-md-7" style="margin-bottom: 15px;">
|
|
{% comment %} Render markdown-style `backticks` as monospace. Segments between paired backticks (odd split indices) become <code>. {% endcomment %}
|
|
{% assign desc_parts = item.description | split: '`' %}
|
|
{% capture rendered_description %}{% for desc_part in desc_parts %}{% assign part_parity = forloop.index0 | modulo: 2 %}{% if part_parity == 1 %}<code>{{ desc_part }}</code>{% else %}{{ desc_part }}{% endif %}{% endfor %}{% endcapture %}
|
|
<p style="color: #444;">{{ rendered_description }}</p>
|
|
{% if item.exploitable_under_gvisor and item.mitigation_gap != nil and item.mitigation_gap != '' %}
|
|
<div style="margin-top: 10px;"><strong>Mitigation Gap:</strong> <span style="color: #555;">{{ item.mitigation_gap }}</span></div>
|
|
{% endif %}
|
|
{% if item.exploitable_under_gvisor and item.vm_prevented != nil %}
|
|
<div style="margin-top: 10px;"><strong>VM Runtime Prevented:</strong> <span style="color: #555;">{% if item.vm_prevented %}Yes{% else %}No{% endif %}</span></div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="col-md-5 cve-meta-col">
|
|
<div style="margin-bottom: 6px;"><strong>Escalation Vector:</strong> <span style="color: #555;">{{ item.risk }}</span></div>
|
|
<div style="margin-bottom: 6px;"><strong>Scope:</strong> <span style="color: #555;">{{ item.scope }}</span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div> <!-- end div with padding -->
|
|
</div> <!-- end container --> |