mirror of
https://github.com/0xMarcio/cve.git
synced 2026-02-12 22:53:11 +00:00
Redesign CVE search UI and fix data path
This commit is contained in:
@@ -7,10 +7,10 @@
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
<script defer src="/assets/site.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<body class="color-no-search">
|
||||
<header class="site-header">
|
||||
<div class="wrap">
|
||||
<div class="brand"><a href="/">CVE PoC Hub</a></div>
|
||||
<div class="brand"><a href="/">CVE PoC Hub</a><span>daily</span></div>
|
||||
<nav>
|
||||
<a href="/search/">PoC Search</a>
|
||||
<a href="/kev/">KEV</a>
|
||||
@@ -20,8 +20,51 @@
|
||||
</div>
|
||||
</header>
|
||||
<main class="wrap">
|
||||
<section>
|
||||
<h1>KEV with high EPSS</h1>
|
||||
<section class="hero" data-search-root>
|
||||
<p class="eyebrow">CVE PoC search & intel</p>
|
||||
<h1>Search PoCs, KEV, and EPSS in one place</h1>
|
||||
<p class="lede">Pulls PoC references from <code>github.txt</code>, daily CVE descriptions, CISA KEV, and FIRST EPSS so you can quickly find relevant exploits or risk data.</p>
|
||||
<div class="pill-row tight">
|
||||
<span class="pill"><strong>Search</strong> CVE, vendor, product, or keyword</span>
|
||||
<span class="pill">Negative terms supported (<strong>-windows</strong>)</span>
|
||||
<span class="pill">Links out to MITRE + PoC repos</span>
|
||||
<span class="pill">Nightly GitHub Action refresh</span>
|
||||
</div>
|
||||
<form class="searchForm" action="#">
|
||||
<input type="text" class="search" placeholder="Search CVE, vendor, product, or keyword" autocomplete="off">
|
||||
</form>
|
||||
<div class="search-meta">
|
||||
<span>Loads from <code>CVE_list.json</code></span>
|
||||
<span>Updated daily</span>
|
||||
<span>Max 10k results for performance</span>
|
||||
</div>
|
||||
<div class="search-results" data-results style="display:none">
|
||||
<div class="header">
|
||||
<h2>Results</h2>
|
||||
<span class="muted">Fast monospace table for quick scanning</span>
|
||||
</div>
|
||||
<div class="noResults">No results yet.</div>
|
||||
<div class="results-table hide">
|
||||
<table class="results">
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="18%">
|
||||
CVE
|
||||
</td>
|
||||
<td>
|
||||
Description / PoC links
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="results"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h1>KEV with high EPSS</h1>
|
||||
<p class="muted">KEV items that also carry high EPSS probability.</p>
|
||||
<div class="card-grid">
|
||||
<article class="card">
|
||||
<div class="card-title"><a href="/cve/CVE-2025-9242.html">CVE-2025-9242</a></div>
|
||||
@@ -131,8 +174,9 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section class="section">
|
||||
<h1>EPSS picks not in KEV</h1>
|
||||
<p class="muted">High-probability EPSS items that are not yet in the KEV list.</p>
|
||||
<div class="card-grid">
|
||||
<article class="card">
|
||||
<div class="card-title"><a href="/cve/CVE-2025-9316.html">CVE-2025-9316</a></div>
|
||||
@@ -147,8 +191,9 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section class="section">
|
||||
<h1>Trending PoCs</h1>
|
||||
<p class="muted">Fresh GitHub PoCs by stars and recency.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="list">
|
||||
<thead><tr><th>Stars</th><th>Updated</th><th>Name</th><th>Description</th></tr></thead>
|
||||
@@ -278,8 +323,9 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section class="section">
|
||||
<h1>Changes since yesterday</h1>
|
||||
<p class="muted">Quick snapshot of the latest diffs in the feeds.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="list">
|
||||
<thead><tr><th>Type</th><th>Count</th><th>Examples</th></tr></thead>
|
||||
@@ -314,5 +360,6 @@ None </td>
|
||||
<span><a href="https://github.com/0xMarcio/cve">GitHub repo</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
<script src="/logic.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
100
docs/logic.js
100
docs/logic.js
@@ -1,14 +1,12 @@
|
||||
const searchResultFormat = '<tr><td class="cveNum">$cve</td><td align="left">$description $poc</td></tr>';
|
||||
const searchResultFormat = '<tr><td class="cveNum">$cve</td><td class="desc">$description $poc</td></tr>';
|
||||
const totalLimit = 10000;
|
||||
const replaceStrings = ['HackTheBox - ', 'VulnHub - ', 'UHC - '];
|
||||
const results = document.querySelector('div.results');
|
||||
const searchValue = document.querySelector('input.search');
|
||||
const form = document.querySelector('form.searchForm');
|
||||
const resultsTableHideable = document.querySelector('.results-table');
|
||||
const resultsTable = document.querySelector('tbody.results');
|
||||
const noResults = document.querySelector('div.noResults');
|
||||
const colorUpdate = document.body;
|
||||
|
||||
function getSearchRoot() {
|
||||
return document.querySelector('[data-search-root]');
|
||||
}
|
||||
|
||||
function escapeHTML(str) {
|
||||
return str.replace(/[&<>"']/g, match => ({
|
||||
'&': '&',
|
||||
@@ -23,10 +21,10 @@ function convertLinksToList(links) {
|
||||
if (links.length === 0) {
|
||||
return '';
|
||||
}
|
||||
let htmlOutput = `<hr><div class="poc-container"><ul>`;
|
||||
let htmlOutput = `<div class="poc-container"><ul>`;
|
||||
const displayLimit = 5;
|
||||
links.slice(0, displayLimit).forEach(link => {
|
||||
htmlOutput += `<li><a target="_blank" href="${link}">${link}</a></li>`;
|
||||
htmlOutput += `<li><a target="_blank" href="${link}">${link}</a></li>`;
|
||||
});
|
||||
htmlOutput += `</ul>`;
|
||||
if (links.length > displayLimit) {
|
||||
@@ -50,8 +48,7 @@ function toggleDropdown(button) {
|
||||
button.textContent = "Show More";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window.toggleDropdown = toggleDropdown;
|
||||
|
||||
function getCveLink(cveId) {
|
||||
return `<a target="_blank" href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=${cveId}"><b>${cveId}</b></a>`;
|
||||
@@ -59,16 +56,16 @@ function getCveLink(cveId) {
|
||||
|
||||
const controls = {
|
||||
oldColor: '',
|
||||
displayResults() {
|
||||
displayResults(results, resultsTableHideable) {
|
||||
results.style.display = '';
|
||||
resultsTableHideable.classList.remove('hide');
|
||||
},
|
||||
hideResults() {
|
||||
hideResults(results, resultsTableHideable) {
|
||||
results.style.display = 'none';
|
||||
resultsTableHideable.classList.add('hide');
|
||||
},
|
||||
doSearch(match, dataset) {
|
||||
const words = match.toLowerCase().split(' ');
|
||||
const words = match.toLowerCase().split(' ').filter(Boolean);
|
||||
const posmatch = words.filter(word => word[0] !== '-');
|
||||
const negmatch = words.filter(word => word[0] === '-').map(word => word.substring(1));
|
||||
|
||||
@@ -82,10 +79,10 @@ const controls = {
|
||||
return positiveMatch && !negativeMatch;
|
||||
});
|
||||
},
|
||||
updateResults(loc, results) {
|
||||
updateResults(loc, results, noResults, resultsTableHideable) {
|
||||
if (results.length === 0) {
|
||||
noResults.style.display = '';
|
||||
noResults.textContent = 'No Results Found';
|
||||
noResults.textContent = 'No results found — try another vendor, product, or CVE id.';
|
||||
resultsTableHideable.classList.add('hide');
|
||||
} else if (results.length > totalLimit) {
|
||||
noResults.style.display = '';
|
||||
@@ -93,7 +90,7 @@ const controls = {
|
||||
noResults.textContent = 'Error: ' + results.length + ' results were found, try being more specific';
|
||||
this.setColor(colorUpdate, 'too-many-results');
|
||||
} else {
|
||||
loc.innerHTML = ''; // Clear existing rows
|
||||
loc.innerHTML = '';
|
||||
|
||||
noResults.style.display = 'none';
|
||||
resultsTableHideable.classList.remove('hide');
|
||||
@@ -122,8 +119,23 @@ const controls = {
|
||||
window.controls = controls;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const root = getSearchRoot();
|
||||
if (!root) return;
|
||||
|
||||
const results = root.querySelector('[data-results]');
|
||||
const searchValue = root.querySelector('input.search');
|
||||
const form = root.querySelector('form.searchForm');
|
||||
const resultsTableHideable = root.querySelector('.results-table');
|
||||
const resultsTable = root.querySelector('tbody.results');
|
||||
const noResults = root.querySelector('div.noResults');
|
||||
|
||||
document.body.classList.add('fade');
|
||||
|
||||
if (!results || !searchValue || !form || !resultsTableHideable || !resultsTable || !noResults) {
|
||||
console.warn('Search container missing expected elements');
|
||||
return;
|
||||
}
|
||||
|
||||
let currentSet = [];
|
||||
let debounceTimer;
|
||||
|
||||
@@ -131,16 +143,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const val = searchValue.value.trim();
|
||||
|
||||
if (val !== '') {
|
||||
controls.displayResults();
|
||||
controls.displayResults(results, resultsTableHideable);
|
||||
currentSet = window.controls.doSearch(val, window.dataset || []);
|
||||
|
||||
if (currentSet.length < totalLimit) {
|
||||
window.controls.setColor(colorUpdate, currentSet.length === 0 ? 'no-results' : 'results-found');
|
||||
}
|
||||
|
||||
window.controls.updateResults(resultsTable, currentSet);
|
||||
window.controls.updateResults(resultsTable, currentSet, noResults, resultsTableHideable);
|
||||
} else {
|
||||
controls.hideResults();
|
||||
controls.hideResults(results, resultsTableHideable);
|
||||
window.controls.setColor(colorUpdate, 'no-search');
|
||||
noResults.style.display = 'none';
|
||||
}
|
||||
@@ -150,30 +162,40 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
}
|
||||
|
||||
fetch('/CVE_list.json')
|
||||
.then(res => {
|
||||
if (!res.ok) {
|
||||
throw new Error(`Failed to load CVE list (${res.status})`);
|
||||
const cveListCandidates = [
|
||||
new URL('/CVE_list.json', window.location.origin).href,
|
||||
new URL('CVE_list.json', window.location.href).href,
|
||||
new URL('../CVE_list.json', window.location.href).href
|
||||
];
|
||||
|
||||
(async () => {
|
||||
for (const url of cveListCandidates) {
|
||||
try {
|
||||
const res = await fetch(url, { cache: 'no-store' });
|
||||
if (!res.ok) {
|
||||
throw new Error(`Failed to load ${url} (${res.status})`);
|
||||
}
|
||||
const data = await res.json();
|
||||
window.dataset = Array.isArray(data) ? data : [];
|
||||
currentSet = window.dataset;
|
||||
controls.hideResults(results, resultsTableHideable);
|
||||
noResults.style.display = 'none';
|
||||
window.controls.setColor(colorUpdate, 'no-search');
|
||||
return;
|
||||
} catch (err) {
|
||||
console.warn(err.message);
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
window.dataset = Array.isArray(data) ? data : [];
|
||||
currentSet = window.dataset;
|
||||
window.controls.updateResults(resultsTable, window.dataset);
|
||||
doSearch({ type: 'none' });
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
window.dataset = [];
|
||||
noResults.textContent = 'Unable to load CVE list';
|
||||
noResults.style.display = '';
|
||||
});
|
||||
}
|
||||
window.dataset = [];
|
||||
noResults.textContent = 'Unable to load CVE list';
|
||||
noResults.style.display = '';
|
||||
controls.setColor(colorUpdate, 'no-results');
|
||||
})();
|
||||
|
||||
form.addEventListener('submit', doSearch);
|
||||
|
||||
searchValue.addEventListener('input', event => {
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(() => doSearch(event), 300);
|
||||
debounceTimer = setTimeout(() => doSearch(event), 200);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Search utility for CVE PoCs">
|
||||
<link rel="stylesheet" href="../style.css">
|
||||
<title>PoC Search - CVE Radar</title>
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
<title>CVE PoC Hub - Search</title>
|
||||
</head>
|
||||
<body class="color-no-search">
|
||||
<header class="site-header">
|
||||
<div class="wrap">
|
||||
<div class="brand"><a href="/">CVE PoC Hub</a></div>
|
||||
<div class="brand"><a href="/">CVE PoC Hub</a><span>daily</span></div>
|
||||
<nav>
|
||||
<a href="/search/">PoC Search</a>
|
||||
<a href="/kev/">KEV</a>
|
||||
@@ -19,31 +19,39 @@
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container">
|
||||
<div class="search">
|
||||
<div class="header">
|
||||
<h1>CVE PoC Search</h1>
|
||||
<main class="wrap">
|
||||
<section class="hero" data-search-root>
|
||||
<p class="eyebrow">CVE PoC search</p>
|
||||
<h1>Find exploit writeups and PoCs instantly</h1>
|
||||
<p class="lede">Search by CVE id, vendor, product, or keyword. Results are powered by the nightly CVE_list.json feed and link directly to PoC references.</p>
|
||||
<div class="pill-row tight">
|
||||
<span class="pill">Linked PoCs</span>
|
||||
<span class="pill">MITRE CVE pages</span>
|
||||
<span class="pill">Vendor / product filters</span>
|
||||
<span class="pill">Supports negative terms (e.g. <strong>-windows</strong>)</span>
|
||||
</div>
|
||||
<div class="query">
|
||||
<form class="searchForm" action="#">
|
||||
<input type="text" class="search" placeholder="ENTER SEARCH TERM" autocomplete="false">
|
||||
</form>
|
||||
<form class="searchForm" action="#">
|
||||
<input type="text" class="search" placeholder="Search CVE, vendor, product, or keyword" autocomplete="off">
|
||||
</form>
|
||||
<div class="search-meta">
|
||||
<span>Loads from <code>CVE_list.json</code></span>
|
||||
<span>Updated daily via GitHub Actions</span>
|
||||
</div>
|
||||
<div class="results" style="display:none">
|
||||
<br>
|
||||
<div class="noResults">
|
||||
<h2>No Results Found</h2>
|
||||
<div class="search-results" data-results style="display:none">
|
||||
<div class="header">
|
||||
<h2>Results</h2>
|
||||
<span class="muted">Up to 10k rows</span>
|
||||
</div>
|
||||
<div class="results-table">
|
||||
|
||||
<div class="noResults">No results yet.</div>
|
||||
<div class="results-table hide">
|
||||
<table class="results">
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="15%">
|
||||
<td width="18%">
|
||||
CVE
|
||||
</td>
|
||||
<td>
|
||||
Description / POC
|
||||
Description / PoC links
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -51,13 +59,14 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<footer class="site-footer">
|
||||
<div class="wrap">
|
||||
<span>© 0xMarcio 2025</span>
|
||||
<span>Found a bug? <a href="https://github.com/0xMarcio/cve/issues" target="_blank">File it on GitHub</a></span>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© 0xMarcio 2025
|
||||
<br>
|
||||
Found a bug? File it or fix it <a href="https://github.com/0xMarcio/cve/issues">here</a>
|
||||
</div>
|
||||
</div>
|
||||
<script src="../logic.js"></script>
|
||||
</footer>
|
||||
<script src="/logic.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
531
docs/style.css
531
docs/style.css
@@ -1,178 +1,411 @@
|
||||
@import url("https://fonts.googleapis.com/css?family=Source+Code+Pro:400,600&display=swap");
|
||||
@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;600&display=swap");
|
||||
|
||||
:root {
|
||||
--bg: #60a8f0;
|
||||
--panel: rgba(255, 255, 255, 0.15);
|
||||
--text: #041b3a;
|
||||
--text-strong: #00122b;
|
||||
--muted: #0b3c6d;
|
||||
--border: rgba(0, 17, 43, 0.08);
|
||||
--link: #0c4bff;
|
||||
--accent: #073b78;
|
||||
font-family: 'Source Code Pro', monospace;
|
||||
--bg: #0b1021;
|
||||
--bg-2: #0f172a;
|
||||
--panel: rgba(255, 255, 255, 0.04);
|
||||
--panel-strong: rgba(255, 255, 255, 0.08);
|
||||
--text: #e9edf5;
|
||||
--muted: #9bb0d3;
|
||||
--border: rgba(255, 255, 255, 0.08);
|
||||
--border-strong: rgba(255, 255, 255, 0.15);
|
||||
--accent: #7ee0ff;
|
||||
--accent-2: #b097ff;
|
||||
--danger: #ff8a8a;
|
||||
--success: #6ee7b7;
|
||||
font-family: 'Space Grotesk', 'JetBrains Mono', system-ui, -apple-system, sans-serif;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: var(--bg);
|
||||
min-height: 100vh;
|
||||
background: radial-gradient(circle at 20% 20%, rgba(126, 224, 255, 0.1), transparent 25%),
|
||||
radial-gradient(circle at 80% 0%, rgba(176, 151, 255, 0.1), transparent 20%),
|
||||
linear-gradient(145deg, var(--bg) 0%, #0a152b 40%, #090f1c 100%);
|
||||
color: var(--text);
|
||||
font-family: 'Source Code Pro', monospace;
|
||||
font-family: 'Space Grotesk', 'JetBrains Mono', system-ui, -apple-system, sans-serif;
|
||||
line-height: 1.6;
|
||||
overflow-x: hidden;
|
||||
transition: background-color 0.5s;
|
||||
transition: background 0.6s ease;
|
||||
}
|
||||
|
||||
.wrap { width: min(1100px, 96vw); margin: 0 auto; padding: 1.2rem 0; }
|
||||
a { color: var(--accent); text-decoration: none; }
|
||||
a:hover { color: var(--accent-2); }
|
||||
|
||||
.wrap { width: min(1180px, 94vw); margin: 0 auto; padding: 0 0 2rem; }
|
||||
|
||||
.site-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 5;
|
||||
background: rgba(96, 168, 240, 0.95);
|
||||
z-index: 10;
|
||||
background: rgba(8, 12, 26, 0.88);
|
||||
border-bottom: 1px solid var(--border);
|
||||
box-shadow: 0 8px 20px rgba(0,0,0,0.08);
|
||||
backdrop-filter: blur(12px);
|
||||
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
.site-header .wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 1rem 0.5rem;
|
||||
}
|
||||
.brand a {
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
.brand span {
|
||||
display: inline-block;
|
||||
padding: 0.15rem 0.5rem;
|
||||
margin-left: 0.35rem;
|
||||
background: rgba(126, 224, 255, 0.15);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--accent);
|
||||
}
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
nav a {
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
padding: 0.5rem 0.8rem;
|
||||
border-radius: 10px;
|
||||
border: 1px solid transparent;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.01em;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
nav a:hover {
|
||||
border-color: var(--border);
|
||||
background: var(--panel);
|
||||
color: #fff;
|
||||
}
|
||||
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; }
|
||||
.brand a { font-weight: 700; color: var(--text-strong); text-decoration: none; font-size: 1.1rem; }
|
||||
nav a { margin-left: 1rem; color: var(--text-strong); text-decoration: none; opacity: 0.8; font-weight: 600; }
|
||||
nav a:hover { opacity: 1; }
|
||||
|
||||
.site-footer { border-top: 1px solid var(--border); padding: 1rem 0 1.5rem; color: var(--muted); text-align: center; font-size: 0.9rem; background: rgba(255,255,255,0.1); }
|
||||
.site-footer a { color: var(--link); }
|
||||
main { padding-top: 1.5rem; }
|
||||
|
||||
h1, h2, h3 { margin: 0 0 0.6rem; color: var(--text-strong); }
|
||||
p { margin: 0 0 0.75rem; }
|
||||
a { color: var(--link); }
|
||||
.hero {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
padding: 1.5rem;
|
||||
border-radius: 18px;
|
||||
background: linear-gradient(145deg, rgba(126, 224, 255, 0.08), rgba(176, 151, 255, 0.08));
|
||||
border: 1px solid var(--border-strong);
|
||||
box-shadow: 0 30px 80px rgba(0,0,0,0.35);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hero::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(circle at 80% 20%, rgba(126,224,255,0.14), transparent 35%),
|
||||
radial-gradient(circle at 10% 90%, rgba(176,151,255,0.12), transparent 30%);
|
||||
pointer-events: none;
|
||||
}
|
||||
.hero > * { position: relative; z-index: 1; }
|
||||
.hero .eyebrow {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
margin: 0;
|
||||
}
|
||||
.hero h1 {
|
||||
margin: 0.2rem 0 0.3rem;
|
||||
font-size: clamp(2.1rem, 4vw, 2.8rem);
|
||||
letter-spacing: -0.02em;
|
||||
color: #fff;
|
||||
}
|
||||
.hero .lede {
|
||||
margin: 0 0 0.8rem;
|
||||
color: var(--muted);
|
||||
max-width: 780px;
|
||||
}
|
||||
.hero .pill-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
padding: 0.35rem 0.75rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.pill strong { color: #fff; }
|
||||
|
||||
.card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; }
|
||||
.card { background: var(--panel); padding: 1rem; border-radius: 12px; border: 1px solid var(--border); box-shadow: 0 10px 24px rgba(0,0,0,0.08); }
|
||||
.card-title { font-weight: 700; margin-bottom: 0.3rem; color: var(--text-strong); }
|
||||
.searchForm {
|
||||
width: 100%;
|
||||
}
|
||||
.searchForm input[type="text"],
|
||||
.searchForm input[type="search"] {
|
||||
width: 100%;
|
||||
padding: 1.1rem 1.25rem;
|
||||
border-radius: 14px;
|
||||
border: 1px solid var(--border-strong);
|
||||
background: rgba(6, 10, 22, 0.8);
|
||||
color: #fff;
|
||||
font-size: 1.05rem;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
outline: none;
|
||||
box-shadow: inset 0 0 0 1px rgba(126, 224, 255, 0.05), 0 16px 32px rgba(0,0,0,0.35);
|
||||
}
|
||||
.searchForm input::placeholder { color: #7c8aab; }
|
||||
|
||||
.search-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.search-results {
|
||||
margin-top: 1rem;
|
||||
border-radius: 14px;
|
||||
border: 1px solid var(--border);
|
||||
background: rgba(8, 12, 26, 0.8);
|
||||
overflow: hidden;
|
||||
}
|
||||
.search-results .header {
|
||||
padding: 0.75rem 1.1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.search-results .header h2 {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
letter-spacing: 0.02em;
|
||||
color: #fff;
|
||||
}
|
||||
.search-results table.results {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.search-results table.results thead td {
|
||||
font-weight: 700;
|
||||
color: var(--muted);
|
||||
padding: 0.75rem 1rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.search-results table.results tbody tr {
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
.search-results table.results td {
|
||||
padding: 0.9rem 1rem;
|
||||
vertical-align: top;
|
||||
color: var(--text);
|
||||
}
|
||||
.search-results table.results td.desc {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.cveNum { font-weight: 700; font-size: 1.05rem; }
|
||||
.poc-container { margin-top: 0.4rem; }
|
||||
.poc-container ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.3rem; }
|
||||
.poc-container li a { word-break: break-all; color: var(--accent); }
|
||||
.dropdown-btn {
|
||||
margin-top: 0.4rem;
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 50px;
|
||||
padding: 0.35rem 0.8rem;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.results-table.hide { display: none; }
|
||||
.noResults {
|
||||
padding: 0.8rem 1rem;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 1rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.card {
|
||||
background: linear-gradient(180deg, rgba(255,255,255,0.06) 0%, rgba(255,255,255,0.03) 100%);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
padding: 1rem;
|
||||
box-shadow: 0 16px 40px rgba(0,0,0,0.4);
|
||||
display: grid;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.card-title { font-weight: 700; color: #fff; font-size: 1rem; }
|
||||
.card-meta { color: var(--muted); font-size: 0.95rem; }
|
||||
.card p { margin: 0; color: #c6d1ea; }
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.25rem 0.55rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(126, 224, 255, 0.12);
|
||||
color: var(--text);
|
||||
font-size: 0.85rem;
|
||||
margin-right: 0.3rem;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.muted { color: var(--muted); }
|
||||
|
||||
.filter, input[type="search"], input[type="text"] {
|
||||
width: 100%;
|
||||
padding: 0.75rem;
|
||||
border-radius: 10px;
|
||||
.section {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
.section h1, .section h2 {
|
||||
margin: 0 0 0.25rem;
|
||||
color: #fff;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
.section p { margin: 0; color: var(--muted); }
|
||||
|
||||
.table-responsive {
|
||||
margin-top: 1rem;
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--border);
|
||||
background: rgba(255,255,255,0.9);
|
||||
font-family: inherit;
|
||||
font-size: 1rem;
|
||||
color: var(--text-strong);
|
||||
background: rgba(8, 12, 26, 0.9);
|
||||
box-shadow: 0 16px 40px rgba(0,0,0,0.35);
|
||||
}
|
||||
.table-responsive table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.table-responsive th,
|
||||
.table-responsive td {
|
||||
padding: 0.85rem 0.9rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
text-align: left;
|
||||
color: var(--text);
|
||||
}
|
||||
.table-responsive th {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
color: var(--muted);
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
.table-responsive tr:nth-child(odd) td { background: rgba(255, 255, 255, 0.02); }
|
||||
.filter {
|
||||
width: 100%;
|
||||
padding: 0.75rem 0.9rem;
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border);
|
||||
background: rgba(7, 12, 24, 0.85);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.table-responsive { overflow-x: auto; border: 1px solid var(--border); border-radius: 12px; background: rgba(255,255,255,0.9); box-shadow: 0 12px 28px rgba(0,0,0,0.1); }
|
||||
.table-responsive table { width: 100%; border-collapse: collapse; }
|
||||
.table-responsive th, .table-responsive td { padding: 0.85rem 0.9rem; border-bottom: 1px solid var(--border); text-align: left; color: var(--text-strong); }
|
||||
.table-responsive th { background: rgba(0,0,0,0.04); color: var(--text-strong); letter-spacing: 0.2px; }
|
||||
.table-responsive tr:nth-child(odd) td { background: rgba(0,0,0,0.02); }
|
||||
|
||||
.color-no-search { background: #60a8f0; }
|
||||
.color-no-results { background: #fa5e3d; }
|
||||
.color-results-found { background: #30c266; }
|
||||
.color-too-many-results { background: #fa8840; }
|
||||
|
||||
.container { display: flex; min-height: calc(100vh - 70px); flex-direction: column; justify-content: space-between; text-align: center; margin: 0 auto; padding: 1rem; }
|
||||
.container .search .header { padding-bottom: 1rem; }
|
||||
.container .search .header h1 { font-size: 3.4rem; margin: 0.5rem; color: var(--text-strong); }
|
||||
.container .search .query input { width: 100%; height: 5rem; font-size: 2rem; text-align: center; margin: 0; padding: 0 1rem; border: 0; outline: none; border-radius: 12px; background: rgba(255,255,255,0.95); }
|
||||
.container .search .results .results-table.hide { display: none; }
|
||||
.container .search .results .results-table table.results { table-layout: fixed; border: 0; width: 100%; margin: 0; }
|
||||
@media screen and (min-width: 800px) {
|
||||
.container .search .results .results-table table.results { margin-left: 5vw; margin-right: 5vw; width: 90vw; }
|
||||
}
|
||||
.container .search .results .results-table table.results thead { font-size: 1.2rem; }
|
||||
.container .search .results .results-table table.results tbody tr:nth-child(odd) { background-color: rgba(255, 255, 255, 0.2); }
|
||||
.container .footer { background-color: rgba(255, 255, 255, 0.05); padding: 1rem; }
|
||||
.container a { color: #0c4bff; text-decoration: none; }
|
||||
|
||||
.badge { display: inline-block; background: rgba(12,75,255,0.12); color: var(--text-strong); padding: 0.2rem 0.6rem; border-radius: 999px; font-size: 0.85rem; }
|
||||
|
||||
.pill-row { display: flex; flex-wrap: wrap; gap: 0.4rem; }
|
||||
.pill { padding: 0.3rem 0.5rem; border-radius: 999px; background: rgba(255,255,255,0.8); color: var(--text-strong); border: 1px solid var(--border); font-size: 0.85rem; }
|
||||
|
||||
.hero, .section { margin-bottom: 1.5rem; }
|
||||
|
||||
@media screen and (min-width: 800px) {
|
||||
body .container .search .results .results-table table.results thead {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
body .container .search .results .results-table table.results tbody td {
|
||||
padding: 0.5rem 5px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
body .container .search .results .results-table table.results tbody tr {
|
||||
.site-footer {
|
||||
border-top: 1px solid var(--border);
|
||||
padding: 1rem 0 1.5rem;
|
||||
color: var(--muted);
|
||||
text-align: center;
|
||||
font-size: 0.9rem;
|
||||
max-width: 10vw;
|
||||
background: rgba(8, 12, 26, 0.8);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
.site-footer a { color: var(--accent); }
|
||||
.site-footer .wrap { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; align-items: center; }
|
||||
|
||||
.color-no-search { background: linear-gradient(145deg, #0b1021 0%, #0d172e 60%, #0a0f1e 100%); }
|
||||
.color-no-results { background: radial-gradient(circle at 20% 20%, rgba(255,138,138,0.15), transparent 35%), var(--bg); }
|
||||
.color-results-found { background: radial-gradient(circle at 15% 20%, rgba(110,231,183,0.12), transparent 32%), var(--bg); }
|
||||
.color-too-many-results { background: radial-gradient(circle at 30% 10%, rgba(255,188,99,0.12), transparent 28%), var(--bg); }
|
||||
|
||||
.subtle-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.stat {
|
||||
padding: 0.75rem 0.9rem;
|
||||
border-radius: 12px;
|
||||
background: rgba(255,255,255,0.04);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.stat strong { display: block; color: #fff; font-size: 1.2rem; }
|
||||
.stat span { color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.pill-row.tight { gap: 0.25rem; }
|
||||
|
||||
.topbar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 9;
|
||||
background: rgba(8, 12, 26, 0.92);
|
||||
border-bottom: 1px solid var(--border);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
.topbar .wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.9rem 0.5rem;
|
||||
}
|
||||
.topbar nav { display: flex; gap: 0.6rem; }
|
||||
.topbar nav a {
|
||||
color: var(--text);
|
||||
padding: 0.45rem 0.7rem;
|
||||
border-radius: 10px;
|
||||
border: 1px solid transparent;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.topbar nav a:hover { border-color: var(--border); background: var(--panel); color: #fff; }
|
||||
.dot { color: var(--accent); margin-right: 0.35rem; }
|
||||
.small { font-size: 0.9rem; }
|
||||
.footer { padding: 1.2rem 0; border-top: 1px solid var(--border); color: var(--muted); background: rgba(8,12,26,0.85); }
|
||||
.footer-inner { display: flex; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; }
|
||||
|
||||
.section-header { display: flex; justify-content: space-between; align-items: baseline; gap: 0.6rem; }
|
||||
.section-header h1, .section-header h2 { margin: 0; }
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
padding: 0.8rem 1rem;
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border);
|
||||
background: rgba(7, 12, 24, 0.85);
|
||||
color: #fff;
|
||||
}
|
||||
.table-wrap {
|
||||
margin-top: 1rem;
|
||||
border-radius: 14px;
|
||||
border: 1px solid var(--border);
|
||||
background: rgba(8,12,26,0.9);
|
||||
overflow: hidden;
|
||||
box-shadow: 0 16px 40px rgba(0,0,0,0.35);
|
||||
}
|
||||
.table-wrap table { width: 100%; border-collapse: collapse; }
|
||||
.table-wrap th, .table-wrap td {
|
||||
padding: 0.85rem 0.9rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
text-align: left;
|
||||
}
|
||||
.table-wrap th { background: rgba(255,255,255,0.03); color: var(--muted); }
|
||||
|
||||
@media screen and (max-width: 720px) {
|
||||
nav { gap: 0.35rem; }
|
||||
nav a { padding: 0.45rem 0.55rem; font-size: 0.95rem; }
|
||||
.hero { padding: 1.15rem; }
|
||||
.search-results table.results td { word-break: break-word; }
|
||||
}
|
||||
|
||||
@media screen and (min-width: 800px) {
|
||||
body .container .search .results .results-table table.results tbody tr {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
body .container .subfooter h3 {
|
||||
padding: 0 4rem;
|
||||
}
|
||||
|
||||
body .container .footer {
|
||||
display: block;
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
padding: 1rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none!important;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul li {
|
||||
display: flex;
|
||||
border-bottom: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
ul li a {
|
||||
text-decoration: none;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
ul li {
|
||||
color: rgb(242, 255, 0);
|
||||
}
|
||||
hr {
|
||||
border: 0;
|
||||
height: 0;
|
||||
box-shadow: 0 0 4px 0.3px #a6ff0087;
|
||||
}
|
||||
.cveNum {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
.poc-container {
|
||||
position: relative;
|
||||
padding-right: 100px; /* Adjust this value if needed */
|
||||
}
|
||||
|
||||
.dropdown-btn {
|
||||
border: 2px solid #ffffff;
|
||||
border-radius: 50px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
font-size: .9rem;
|
||||
padding: .3rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
ul { list-style: none; padding: 0; margin: 0; }
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
<script defer src="/assets/site.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<body class="{{ body_class or '' }}">
|
||||
<header class="site-header">
|
||||
<div class="wrap">
|
||||
<div class="brand"><a href="/">CVE PoC Hub</a></div>
|
||||
<div class="brand"><a href="/">CVE PoC Hub</a><span>daily</span></div>
|
||||
<nav>
|
||||
<a href="/search/">PoC Search</a>
|
||||
<a href="/kev/">KEV</a>
|
||||
@@ -29,5 +29,6 @@
|
||||
<span><a href="https://github.com/0xMarcio/cve">GitHub repo</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
{% block extra_scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,54 +1,62 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<h1>Daily Diff</h1>
|
||||
<p>Comparing the latest snapshot to the previous one.</p>
|
||||
<section class="section">
|
||||
<h1>Daily Diff</h1>
|
||||
<p class="muted">Comparing the latest snapshot to the previous one.</p>
|
||||
</section>
|
||||
|
||||
<h2>New KEV Entries</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="list">
|
||||
<thead><tr><th>CVE</th><th>Vendor</th><th>Product</th><th>Date Added</th></tr></thead>
|
||||
<tbody>
|
||||
{% for row in diff.new_kev_entries or [] %}
|
||||
<tr>
|
||||
<td><a href="/cve/{{ row.cve }}.html">{{ row.cve }}</a></td>
|
||||
<td>{{ row.vendor }}</td>
|
||||
<td>{{ row.product }}</td>
|
||||
<td>{{ row.date_added }}</td>
|
||||
</tr>
|
||||
{% else %}<tr><td colspan="4">No new KEV entries.</td></tr>{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<section class="section">
|
||||
<h2>New KEV Entries</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="list">
|
||||
<thead><tr><th>CVE</th><th>Vendor</th><th>Product</th><th>Date Added</th></tr></thead>
|
||||
<tbody>
|
||||
{% for row in diff.new_kev_entries or [] %}
|
||||
<tr>
|
||||
<td><a href="/cve/{{ row.cve }}.html">{{ row.cve }}</a></td>
|
||||
<td>{{ row.vendor }}</td>
|
||||
<td>{{ row.product }}</td>
|
||||
<td>{{ row.date_added }}</td>
|
||||
</tr>
|
||||
{% else %}<tr><td colspan="4">No new KEV entries.</td></tr>{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2>New High EPSS</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="list">
|
||||
<thead><tr><th>CVE</th><th>EPSS</th><th>Percentile</th></tr></thead>
|
||||
<tbody>
|
||||
{% for row in diff.new_high_epss or [] %}
|
||||
<tr>
|
||||
<td><a href="/cve/{{ row.cve }}.html">{{ row.cve }}</a></td>
|
||||
<td>{{ '%.3f'|format(row.epss or 0) }}</td>
|
||||
<td>{{ '%2.0f'|format((row.percentile or 0)*100) }}th</td>
|
||||
</tr>
|
||||
{% else %}<tr><td colspan="3">No new high EPSS items.</td></tr>{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<section class="section">
|
||||
<h2>New High EPSS</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="list">
|
||||
<thead><tr><th>CVE</th><th>EPSS</th><th>Percentile</th></tr></thead>
|
||||
<tbody>
|
||||
{% for row in diff.new_high_epss or [] %}
|
||||
<tr>
|
||||
<td><a href="/cve/{{ row.cve }}.html">{{ row.cve }}</a></td>
|
||||
<td>{{ '%.3f'|format(row.epss or 0) }}</td>
|
||||
<td>{{ '%2.0f'|format((row.percentile or 0)*100) }}th</td>
|
||||
</tr>
|
||||
{% else %}<tr><td colspan="3">No new high EPSS items.</td></tr>{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2>Biggest EPSS Movers</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="list">
|
||||
<thead><tr><th>CVE</th><th>Δ EPSS</th><th>Current</th></tr></thead>
|
||||
<tbody>
|
||||
{% for row in diff.epss_movers or [] %}
|
||||
<tr>
|
||||
<td><a href="/cve/{{ row.cve }}.html">{{ row.cve }}</a></td>
|
||||
<td>{{ '%.3f'|format(row.delta) }}</td>
|
||||
<td>{{ '%.3f'|format(row.epss or 0) }}</td>
|
||||
</tr>
|
||||
{% else %}<tr><td colspan="3">No movers yet.</td></tr>{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<section class="section">
|
||||
<h2>Biggest EPSS Movers</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="list">
|
||||
<thead><tr><th>CVE</th><th>Δ EPSS</th><th>Current</th></tr></thead>
|
||||
<tbody>
|
||||
{% for row in diff.epss_movers or [] %}
|
||||
<tr>
|
||||
<td><a href="/cve/{{ row.cve }}.html">{{ row.cve }}</a></td>
|
||||
<td>{{ '%.3f'|format(row.delta) }}</td>
|
||||
<td>{{ '%.3f'|format(row.epss or 0) }}</td>
|
||||
</tr>
|
||||
{% else %}<tr><td colspan="3">No movers yet.</td></tr>{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<h1>EPSS highlights</h1>
|
||||
<p class="muted">This list focuses on CVEs not present in KEV.</p>
|
||||
<input type="search" placeholder="Filter CVE" data-filter-table="epss-table" class="filter" />
|
||||
<div class="table-responsive">
|
||||
<table class="list" id="epss-table">
|
||||
<thead><tr><th>CVE</th><th>EPSS</th><th>Percentile</th><th>PoCs</th></tr></thead>
|
||||
<tbody>
|
||||
{% for row in epss %}
|
||||
<tr>
|
||||
<td><a href="/cve/{{ row.cve }}.html">{{ row.cve }}</a></td>
|
||||
<td>{{ '%.3f'|format(row.epss or 0) }}</td>
|
||||
<td>{{ '%2.0f'|format((row.percentile or 0)*100) }}th</td>
|
||||
<td>{{ row.poc_count }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<section class="section">
|
||||
<h1>EPSS highlights</h1>
|
||||
<p class="muted">High-probability EPSS picks that are not already in KEV. Use the filter to zero in on vendors or products.</p>
|
||||
<input type="search" placeholder="Filter CVE" data-filter-table="epss-table" class="filter" />
|
||||
<div class="table-responsive">
|
||||
<table class="list" id="epss-table">
|
||||
<thead><tr><th>CVE</th><th>EPSS</th><th>Percentile</th><th>PoCs</th></tr></thead>
|
||||
<tbody>
|
||||
{% for row in epss %}
|
||||
<tr>
|
||||
<td><a href="/cve/{{ row.cve }}.html">{{ row.cve }}</a></td>
|
||||
<td>{{ '%.3f'|format(row.epss or 0) }}</td>
|
||||
<td>{{ '%2.0f'|format((row.percentile or 0)*100) }}th</td>
|
||||
<td>{{ row.poc_count }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,7 +1,51 @@
|
||||
{% extends "base.html" %}
|
||||
{% set body_class = "color-no-search" %}
|
||||
{% block content %}
|
||||
<section>
|
||||
<h1>KEV with high EPSS</h1>
|
||||
<section class="hero" data-search-root>
|
||||
<p class="eyebrow">CVE PoC search & intel</p>
|
||||
<h1>Search PoCs, KEV, and EPSS in one place</h1>
|
||||
<p class="lede">Pulls PoC references from <code>github.txt</code>, daily CVE descriptions, CISA KEV, and FIRST EPSS so you can quickly find relevant exploits or risk data.</p>
|
||||
<div class="pill-row tight">
|
||||
<span class="pill"><strong>Search</strong> CVE, vendor, product, or keyword</span>
|
||||
<span class="pill">Negative terms supported (<strong>-windows</strong>)</span>
|
||||
<span class="pill">Links out to MITRE + PoC repos</span>
|
||||
<span class="pill">Nightly GitHub Action refresh</span>
|
||||
</div>
|
||||
<form class="searchForm" action="#">
|
||||
<input type="text" class="search" placeholder="Search CVE, vendor, product, or keyword" autocomplete="off">
|
||||
</form>
|
||||
<div class="search-meta">
|
||||
<span>Loads from <code>CVE_list.json</code></span>
|
||||
<span>Updated daily</span>
|
||||
<span>Max 10k results for performance</span>
|
||||
</div>
|
||||
<div class="search-results" data-results style="display:none">
|
||||
<div class="header">
|
||||
<h2>Results</h2>
|
||||
<span class="muted">Fast monospace table for quick scanning</span>
|
||||
</div>
|
||||
<div class="noResults">No results yet.</div>
|
||||
<div class="results-table hide">
|
||||
<table class="results">
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="18%">
|
||||
CVE
|
||||
</td>
|
||||
<td>
|
||||
Description / PoC links
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="results"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h1>KEV with high EPSS</h1>
|
||||
<p class="muted">KEV items that also carry high EPSS probability.</p>
|
||||
<div class="card-grid">
|
||||
{% for item in data.kev_top[:15] %}
|
||||
<article class="card">
|
||||
@@ -15,8 +59,9 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section class="section">
|
||||
<h1>EPSS picks not in KEV</h1>
|
||||
<p class="muted">High-probability EPSS items that are not yet in the KEV list.</p>
|
||||
<div class="card-grid">
|
||||
{% for item in data.high_epss[:15] %}
|
||||
<article class="card">
|
||||
@@ -28,8 +73,9 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section class="section">
|
||||
<h1>Trending PoCs</h1>
|
||||
<p class="muted">Fresh GitHub PoCs by stars and recency.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="list">
|
||||
<thead><tr><th>Stars</th><th>Updated</th><th>Name</th><th>Description</th></tr></thead>
|
||||
@@ -47,8 +93,9 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section class="section">
|
||||
<h1>Changes since yesterday</h1>
|
||||
<p class="muted">Quick snapshot of the latest diffs in the feeds.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="list">
|
||||
<thead><tr><th>Type</th><th>Count</th><th>Examples</th></tr></thead>
|
||||
@@ -85,3 +132,6 @@
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
{% block extra_scripts %}
|
||||
<script src="/logic.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<h1>Known Exploited Vulnerabilities</h1>
|
||||
<input type="search" placeholder="Filter CVE, vendor, product" data-filter-table="kev-table" class="filter" />
|
||||
<div class="table-responsive">
|
||||
<table class="list" id="kev-table">
|
||||
<thead>
|
||||
<tr><th>CVE</th><th>Vendor</th><th>Product</th><th>EPSS</th><th>Percentile</th><th>Date Added</th><th>Due</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in kev %}
|
||||
<tr>
|
||||
<td><a href="/cve/{{ row.cve }}.html">{{ row.cve }}</a></td>
|
||||
<td>{{ row.vendor }}</td>
|
||||
<td>{{ row.product }}</td>
|
||||
<td>{{ '%.3f'|format(row.epss or 0) }}</td>
|
||||
<td>{{ '%2.0f'|format((row.percentile or 0)*100) }}th</td>
|
||||
<td>{{ row.date_added }}</td>
|
||||
<td>{{ row.due_date or '—' }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<section class="section">
|
||||
<h1>Known Exploited Vulnerabilities</h1>
|
||||
<p class="muted">Filter by CVE, vendor, or product. Rows include EPSS so you can quickly prioritize remediation.</p>
|
||||
<input type="search" placeholder="Filter CVE, vendor, product" data-filter-table="kev-table" class="filter" />
|
||||
<div class="table-responsive">
|
||||
<table class="list" id="kev-table">
|
||||
<thead>
|
||||
<tr><th>CVE</th><th>Vendor</th><th>Product</th><th>EPSS</th><th>Percentile</th><th>Date Added</th><th>Due</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in kev %}
|
||||
<tr>
|
||||
<td><a href="/cve/{{ row.cve }}.html">{{ row.cve }}</a></td>
|
||||
<td>{{ row.vendor }}</td>
|
||||
<td>{{ row.product }}</td>
|
||||
<td>{{ '%.3f'|format(row.epss or 0) }}</td>
|
||||
<td>{{ '%2.0f'|format((row.percentile or 0)*100) }}th</td>
|
||||
<td>{{ row.date_added }}</td>
|
||||
<td>{{ row.due_date or '—' }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user