Align trending PoCs and filter to recent data

This commit is contained in:
0xMarcio
2025-12-17 20:24:46 +01:00
parent da14307c37
commit 0bd6c7ceda
12 changed files with 88 additions and 392 deletions

View File

@@ -59,6 +59,11 @@
async function filterTablesByData() {
const { pocSet, descSet } = await ensureSets();
const currentYear = new Date().getUTCFullYear();
const isRecent = (text) => {
const m = /CVE-(\d{4})-/i.exec(text || '');
return m ? parseInt(m[1], 10) >= currentYear - 1 : false;
};
document.querySelectorAll('table[data-require-poc], table[data-require-desc]').forEach(table => {
for (const row of Array.from(table.querySelectorAll('tbody tr'))) {
const link = row.querySelector('a');
@@ -67,7 +72,7 @@
const needsDesc = table.hasAttribute('data-require-desc');
const hasPoc = pocSet.has(idText);
const hasDesc = descSet.has(idText);
if ((needsPoc && !hasPoc) || (needsDesc && !hasDesc)) {
if ((needsPoc && !hasPoc) || (needsDesc && !hasDesc) || !isRecent(idText)) {
row.remove();
}
}
@@ -87,6 +92,11 @@
return match ? parseInt(match[1], 10) : Infinity;
}
function cveYear(text) {
const m = /cve-(\d{4})-/i.exec(text || '');
return m ? parseInt(m[1], 10) : null;
}
function parseTrendingMarkdown(text) {
const rows = [];
const regex = /^\|\s*(\d+)\s*⭐\s*\|\s*([^|]+)\|\s*\[([^\]]+)\]\(([^)]+)\)\s*\|\s*(.*?)\|$/;
@@ -115,7 +125,12 @@
if (!res.ok) throw new Error('failed to load README');
const text = await res.text();
const entries = parseTrendingMarkdown(text)
.filter(item => item.ageDays <= 5)
.filter(item => item.ageDays <= 4)
.filter(item => {
const currentYear = new Date().getUTCFullYear();
const yr = cveYear(item.name);
return yr !== null && yr >= currentYear - 1;
})
.sort((a, b) => b.stars - a.stars)
.slice(0, 20);

View File

@@ -15,7 +15,6 @@
<a href="/search/">PoC Search</a>
<a href="/kev/">KEV</a>
<a href="/epss/">EPSS</a>
<a href="/diffs/">New KEV</a>
</nav>
</div>
</header>

View File

@@ -1,206 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CVE PoC Hub</title>
<link rel="stylesheet" href="/style.css" />
<script defer src="/assets/site.js"></script>
</head>
<body class="">
<header class="site-header">
<div class="wrap">
<div class="brand"><a href="/">CVE PoC Hub</a></div>
<nav>
<a href="/search/">PoC Search</a>
<a href="/kev/">KEV</a>
<a href="/epss/">EPSS</a>
<a href="/diffs/">New KEV</a>
</nav>
</div>
</header>
<main class="wrap">
<section class="section">
<div class="section-header">
<h1>New KEV entries</h1>
<span class="muted">Only the recent additions</span>
</div>
<div class="table-wrap">
<table data-require-poc>
<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>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-59718">CVE-2025-59718</a></td>
<td>Fortinet</td>
<td>Multiple Products</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-16</td>
<td>2025-12-23</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-14611">CVE-2025-14611</a></td>
<td>Gladinet</td>
<td>CentreStack and Triofox</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-15</td>
<td>2026-01-05</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-43529">CVE-2025-43529</a></td>
<td>Apple</td>
<td>Multiple Products</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-15</td>
<td>2026-01-05</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2018-4063">CVE-2018-4063</a></td>
<td>Sierra Wireless</td>
<td>AirLink ALEOS</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-12</td>
<td>2026-01-02</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-14174">CVE-2025-14174</a></td>
<td>Google</td>
<td>Chromium</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-12</td>
<td>2026-01-02</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-58360">CVE-2025-58360</a></td>
<td>OSGeo</td>
<td>GeoServer</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-11</td>
<td>2026-01-01</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-6218">CVE-2025-6218</a></td>
<td>RARLAB</td>
<td>WinRAR</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-09</td>
<td>2025-12-30</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-62221">CVE-2025-62221</a></td>
<td>Microsoft</td>
<td>Windows</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-09</td>
<td>2025-12-30</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2022-37055">CVE-2022-37055</a></td>
<td>D-Link</td>
<td>Routers</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-08</td>
<td>2025-12-29</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-66644">CVE-2025-66644</a></td>
<td>Array Networks</td>
<td>ArrayOS AG</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-08</td>
<td>2025-12-29</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-55182">CVE-2025-55182</a></td>
<td>Meta</td>
<td>React Server Components</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-05</td>
<td>2025-12-12</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2021-26828">CVE-2021-26828</a></td>
<td>OpenPLC</td>
<td>ScadaBR</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-03</td>
<td>2025-12-24</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-48572">CVE-2025-48572</a></td>
<td>Android</td>
<td>Framework</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-02</td>
<td>2025-12-23</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-48633">CVE-2025-48633</a></td>
<td>Android</td>
<td>Framework</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-12-02</td>
<td>2025-12-23</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2021-26829">CVE-2021-26829</a></td>
<td>OpenPLC</td>
<td>ScadaBR</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-11-28</td>
<td>2025-12-19</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-61757">CVE-2025-61757</a></td>
<td>Oracle</td>
<td>Fusion Middleware</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-11-21</td>
<td>2025-12-12</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-13223">CVE-2025-13223</a></td>
<td>Google</td>
<td>Chromium V8</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-11-19</td>
<td>2025-12-10</td>
</tr>
<tr>
<td class="cve-cell"><a href="/cve/?id=CVE-2025-58034">CVE-2025-58034</a></td>
<td>Fortinet</td>
<td>FortiWeb</td>
<td>0.000</td>
<td> 0th</td>
<td>2025-11-18</td>
<td>2025-11-25</td>
</tr>
</tbody>
</table>
</div>
</section>
</main>
<footer class="site-footer">
<div class="wrap">
<span>Fast CVE triage without the noise.</span>
<span><a href="https://github.com/0xMarcio/cve">GitHub repo</a></span>
</div>
</footer>
</body>
</html>

View File

@@ -15,7 +15,6 @@
<a href="/search/">PoC Search</a>
<a href="/kev/">KEV</a>
<a href="/epss/">EPSS</a>
<a href="/diffs/">New KEV</a>
</nav>
</div>
</header>

View File

@@ -15,7 +15,6 @@
<a href="/search/">PoC Search</a>
<a href="/kev/">KEV</a>
<a href="/epss/">EPSS</a>
<a href="/diffs/">New KEV</a>
</nav>
</div>
</header>
@@ -57,7 +56,7 @@
<section class="section">
<div class="section-header">
<h1>Trending PoCs</h1>
<span class="muted">Most starred PoCs in the past few days</span>
<span class="muted">Recent GitHub movement (last 4 days, sorted by stars)</span>
</div>
<div class="table-wrap" data-trending>
<table>
@@ -71,13 +70,14 @@
</div>
</section>
<section class="section">
<div class="section-header">
<h1>Latest KEV additions</h1>
<span class="muted">Last 30 days</span>
</div>
<div class="table-wrap">
<table data-require-poc>
<table data-require-poc data-require-desc>
<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>
@@ -333,139 +333,6 @@
</div>
</section>
<section class="section">
<div class="section-header">
<h1>Fresh PoCs</h1>
<span class="muted">Recent GitHub movement</span>
</div>
<div class="table-wrap">
<table>
<thead><tr><th>Stars</th><th>Updated</th><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr>
<td>1241</td>
<td>2 hours ago </td>
<td><a href="https://github.com/msanft/CVE-2025-55182" target="_blank">CVE-2025-55182</a></td>
<td class="mono">Explanation and full RCE PoC for CVE-2025-55182 </td>
</tr>
<tr>
<td>775</td>
<td>3 hours ago </td>
<td><a href="https://github.com/ejpir/CVE-2025-55182-research" target="_blank">CVE-2025-55182-research</a></td>
<td class="mono">CVE-2025-55182 POC </td>
</tr>
<tr>
<td>495</td>
<td>8 days ago </td>
<td><a href="https://github.com/WyAtu/CVE-2018-20250" target="_blank">CVE-2018-20250</a></td>
<td class="mono">exp for https://research.checkpoint.com/extracting-code-execution-from-winrar </td>
</tr>
<tr>
<td>607</td>
<td>20 hours ago </td>
<td><a href="https://github.com/mverschu/CVE-2025-33073" target="_blank">CVE-2025-33073</a></td>
<td class="mono">PoC Exploit for the NTLM reflection SMB flaw. </td>
</tr>
<tr>
<td>496</td>
<td>4 days ago </td>
<td><a href="https://github.com/pr0v3rbs/CVE-2025-32463_chwoot" target="_blank">CVE-2025-32463_chwoot</a></td>
<td class="mono">Escalation of Privilege to the root through sudo binary with chroot option. CVE-2025-32463 </td>
</tr>
<tr>
<td>419</td>
<td>5 hours ago </td>
<td><a href="https://github.com/kh4sh3i/CVE-2025-32463" target="_blank">CVE-2025-32463</a></td>
<td class="mono">Local Privilege Escalation to Root via Sudo chroot in Linux </td>
</tr>
<tr>
<td>305</td>
<td>1 day ago </td>
<td><a href="https://github.com/soltanali0/CVE-2025-53770-Exploit" target="_blank">CVE-2025-53770-Exploit</a></td>
<td class="mono">SharePoint WebPart Injection Exploit Tool </td>
</tr>
<tr>
<td>289</td>
<td>4 hours ago </td>
<td><a href="https://github.com/emredavut/CVE-2025-55182" target="_blank">CVE-2025-55182</a></td>
<td class="mono">RSC/Next.js RCE Vulnerability Detector &amp; PoC Chrome Extension CVE-2025-55182 &amp; CVE-2025-66478 </td>
</tr>
<tr>
<td>901</td>
<td>1 hour ago </td>
<td><a href="https://github.com/lachlan2k/React2Shell-CVE-2025-55182-original-poc" target="_blank">React2Shell-CVE-2025-55182-original-poc</a></td>
<td class="mono">Original Proof-of-Concepts for React2Shell CVE-2025-55182 </td>
</tr>
<tr>
<td>386</td>
<td>4 days ago </td>
<td><a href="https://github.com/0x6rss/CVE-2025-24071_PoC" target="_blank">CVE-2025-24071_PoC</a></td>
<td class="mono">CVE-2025-24071: NTLM Hash Leak via RAR/ZIP Extraction and .library-ms File </td>
</tr>
<tr>
<td>207</td>
<td>1 day ago </td>
<td><a href="https://github.com/leesh3288/CVE-2025-32023" target="_blank">CVE-2025-32023</a></td>
<td class="mono">PoC &amp; Exploit for CVE-2025-32023 / PlaidCTF 2025 &#34;Zerodeo&#34; </td>
</tr>
<tr>
<td>396</td>
<td>6 days ago </td>
<td><a href="https://github.com/yuuouu/ColorOS-CVE-2025-10184" target="_blank">ColorOS-CVE-2025-10184</a></td>
<td class="mono">ColorOS短信漏洞以及用户自救方案 </td>
</tr>
<tr>
<td>180</td>
<td>6 days ago </td>
<td><a href="https://github.com/absholi7ly/POC-CVE-2025-24813" target="_blank">POC-CVE-2025-24813</a></td>
<td class="mono">his repository contains an automated Proof of Concept (PoC) script for exploiting **CVE-2025-24813**, a Remote Code Execution (RCE) vulnerability in Apache Tomcat. The vulnerability allows an attacker to upload a malicious serialized payload to the server, leading to arbitrary code execution via deserialization when specific conditions are met. </td>
</tr>
<tr>
<td>256</td>
<td>15 minutes ago </td>
<td><a href="https://github.com/zack0x01/CVE-2025-55182-advanced-scanner-" target="_blank">CVE-2025-55182-advanced-scanner-</a></td>
<td class="mono"></td>
</tr>
<tr>
<td>357</td>
<td>1 hour ago </td>
<td><a href="https://github.com/Malayke/Next.js-RSC-RCE-Scanner-CVE-2025-66478" target="_blank">Next.js-RSC-RCE-Scanner-CVE-2025-66478</a></td>
<td class="mono">A command-line scanner for batch detection of Next.js application versions and determining if they are affected by CVE-2025-66478 vulnerability. </td>
</tr>
<tr>
<td>198</td>
<td>4 days ago </td>
<td><a href="https://github.com/ThumpBo/CVE-2025-30208-EXP" target="_blank">CVE-2025-30208-EXP</a></td>
<td class="mono">CVE-2025-30208-EXP </td>
</tr>
<tr>
<td>73</td>
<td>6 days ago </td>
<td><a href="https://github.com/4daysday/cve-2025-8088" target="_blank">cve-2025-8088</a></td>
<td class="mono">Path traversal tool based on cve-2025-8088 </td>
</tr>
<tr>
<td>163</td>
<td>1 day ago </td>
<td><a href="https://github.com/ZeroMemoryEx/CVE-2025-26125" target="_blank">CVE-2025-26125</a></td>
<td class="mono">( 0day ) Local Privilege Escalation in IObit Malware Fighter </td>
</tr>
<tr>
<td>153</td>
<td>8 days ago </td>
<td><a href="https://github.com/hoefler02/CVE-2025-21756" target="_blank">CVE-2025-21756</a></td>
<td class="mono">Exploit for CVE-2025-21756 for Linux kernel 6.6.75. My first linux kernel exploit! </td>
</tr>
<tr>
<td>136</td>
<td>27 days ago </td>
<td><a href="https://github.com/platsecurity/CVE-2025-32433" target="_blank">CVE-2025-32433</a></td>
<td class="mono">CVE-2025-32433 https://github.com/erlang/otp/security/advisories/GHSA-37cp-fgq5-7wc2 </td>
</tr>
</tbody>
</table>
</div>
</section>
</main>
<footer class="site-footer">
<div class="wrap">

View File

@@ -15,7 +15,6 @@
<a href="/search/">PoC Search</a>
<a href="/kev/">KEV</a>
<a href="/epss/">EPSS</a>
<a href="/diffs/">New KEV</a>
</nav>
</div>
</header>
@@ -27,7 +26,7 @@
</div>
<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" data-require-poc>
<table class="list" id="kev-table" data-require-poc data-require-desc>
<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>

View File

@@ -56,6 +56,13 @@ function getCveLink(cveId) {
function prepareDataset(raw) {
if (!Array.isArray(raw)) return [];
const currentYear = new Date().getUTCFullYear();
const isRecent = (cve) => {
const match = /^CVE-(\d{4})-/i.exec(cve || '');
if (!match) return false;
const year = parseInt(match[1], 10);
return year >= currentYear - 1;
};
const descKeyCleaned = (entry) => {
const base = entry.desc || '';
return replaceStrings.reduce((desc, str) => desc.replace(str, ''), base);
@@ -63,7 +70,7 @@ function prepareDataset(raw) {
return raw
.filter(entry => {
const desc = (entry.desc || '').trim();
return desc && Array.isArray(entry.poc) && entry.poc.length > 0;
return desc && Array.isArray(entry.poc) && entry.poc.length > 0 && isRecent(entry.cve || '');
})
.map(entry => {
const descCleaned = descKeyCleaned(entry);

View File

@@ -15,8 +15,7 @@
<a href="/search/">PoC Search</a>
<a href="/kev/">KEV</a>
<a href="/epss/">EPSS</a>
<a href="/diffs/">New KEV</a>
</nav>
</nav>
</div>
</header>
<main class="wrap">

View File

@@ -24,6 +24,7 @@ EPSS_PATH = DATA_DIR / "epss.json"
DEFAULT_TOP_KEV = 75
DEFAULT_HIGH_EPSS_LIMIT = 50
DEFAULT_HIGH_EPSS_THRESHOLD = 0.05
RECENT_YEAR_WINDOW = 1
def load_inputs(kev_path: Path, epss_path: Path) -> Tuple[Dict, Dict]:
@@ -34,11 +35,22 @@ def load_inputs(kev_path: Path, epss_path: Path) -> Tuple[Dict, Dict]:
def enrich_kev(kev_items: List[Dict], epss_lookup: Dict[str, Dict], poc_index: Dict[str, Dict]) -> List[Dict]:
enriched = []
current_year = today_str()
current_year_int = int(current_year.split("-")[0])
def is_recent(cve_id: str) -> bool:
try:
year = int(cve_id.split("-")[1])
except Exception:
return False
return year >= current_year_int - RECENT_YEAR_WINDOW
for entry in kev_items:
cve = entry.get("cve") or entry.get("cveID") or ""
if not cve:
continue
cve = cve.upper()
if not is_recent(cve):
continue
epss_info = epss_lookup.get(cve, {})
poc_info = poc_index.get(cve)
if not poc_info or not poc_info.get("poc"):
@@ -75,6 +87,14 @@ def build_high_epss_not_in_kev(
threshold: float,
limit: int,
) -> List[Dict]:
current_year_int = int(today_str().split("-")[0])
def is_recent(cve_id: str) -> bool:
try:
year = int(cve_id.split("-")[1])
except Exception:
return False
return year >= current_year_int - RECENT_YEAR_WINDOW
ranked = sorted(
(
row
@@ -82,6 +102,7 @@ def build_high_epss_not_in_kev(
if row.get("cve")
and row.get("cve", "").upper() not in kev_set
and (row.get("epss") is not None)
and is_recent(row.get("cve", ""))
),
key=lambda row: (-float(row.get("epss") or 0), row.get("cve", "")),
)

View File

@@ -1,7 +1,9 @@
from __future__ import annotations
import argparse
from datetime import datetime, timezone
from pathlib import Path
import re
from typing import Dict, Tuple
from jinja2 import Environment, FileSystemLoader, select_autoescape
@@ -59,7 +61,29 @@ def build_pages(env: Environment, data: Dict, diff: Dict | None = None, html_mod
joined = data["joined"]
details = data["details"]
vendors = data["vendors"]
trending = parse_trending_from_readme(README_PATH)
def is_recent_label(label: str) -> bool:
label = (label or "").lower()
if "minute" in label or "hour" in label:
return True
m = re.search(r"(\d+)\\s*day", label)
if not m:
return False
return int(m.group(1)) <= 4
current_year = datetime.now(timezone.utc).year
def extract_year(name: str) -> int | None:
m = re.search(r"cve-(\\d{4})-", name.lower())
return int(m.group(1)) if m else None
trending_raw = parse_trending_from_readme(README_PATH)
trending = [
row
for row in trending_raw
if is_recent_label(row.get("updated", ""))
and (extract_year(row.get("name", "")) or current_year) >= current_year - 1
]
trending.sort(key=lambda r: int(r.get("stars") or 0), reverse=True)
recent_kev = (diff or {}).get("new_kev_entries") or []
metrics = {
"kev_total": len(data["kev_enriched"]),

View File

@@ -15,7 +15,6 @@
<a href="/search/">PoC Search</a>
<a href="/kev/">KEV</a>
<a href="/epss/">EPSS</a>
<a href="/diffs/">New KEV</a>
</nav>
</div>
</header>

View File

@@ -37,27 +37,22 @@
<section class="section">
<div class="section-header">
<h1>Latest KEV additions</h1>
<span class="muted">Last 30 days</span>
<h1>Trending PoCs</h1>
<span class="muted">Recent GitHub movement (last 4 days, sorted by stars)</span>
</div>
<div class="table-wrap">
<div class="table-wrap" data-trending>
<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 recent_kev %}
<thead><tr><th>Stars</th><th>Updated</th><th>Name</th><th>Description</th></tr></thead>
<tbody id="trending-body">
{% for row in trending %}
<tr>
<td class="cve-cell"><a href="/cve/?id={{ row.cve }}">{{ 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>
<td>{{ row.stars }}</td>
<td>{{ row.updated }}</td>
<td><a href="{{ row.url }}" target="_blank">{{ row.name }}</a></td>
<td class="mono">{{ row.desc }}</td>
</tr>
{% else %}
<tr><td colspan="7">No recent KEV entries.</td></tr>
<tr><td colspan="4" class="muted">No recent PoCs.</td></tr>
{% endfor %}
</tbody>
</table>
@@ -70,7 +65,7 @@
<span class="muted">Sorted by score</span>
</div>
<div class="table-wrap">
<table>
<table data-require-poc data-require-desc>
<thead><tr><th>CVE</th><th>EPSS</th><th>Percentile</th><th>PoCs</th><th>Summary</th></tr></thead>
<tbody>
{% for row in data.high_epss %}
@@ -88,28 +83,6 @@
</table>
</div>
</section>
<section class="section">
<div class="section-header">
<h1>Fresh PoCs</h1>
<span class="muted">Recent GitHub movement</span>
</div>
<div class="table-wrap">
<table>
<thead><tr><th>Stars</th><th>Updated</th><th>Name</th><th>Description</th></tr></thead>
<tbody>
{% for row in trending[:20] %}
<tr>
<td>{{ row.stars }}</td>
<td>{{ row.updated }}</td>
<td><a href="{{ row.url }}" target="_blank">{{ row.name }}</a></td>
<td class="mono">{{ row.desc }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</section>
{% endblock %}
{% block extra_scripts %}
<script src="/logic.js"></script>