Stop tracking generated site data

Pages builds from the workflow artifact, so the committed CVE_list.json
was never served while adding a fresh 53 MB blob to history every day.
Generate it during the Pages build instead and drop the duplicate
generator; scripts/build_site.py is now the only thing that writes it.

The jinja2 templates re-rendered a trending table that logic.js replaces
on load, so the page shell goes back to being a plain static file and the
Pages build no longer installs anything. Shallow-clone the sync job too:
it never reads git history, and the three-day lookback already recovers
a skipped day.
This commit is contained in:
0xMarcio committed 2026-08-30 16:59:31 +02:00
1 parent b1ac17daf9
commit f9fc5ae28d
11 files changed
+175 -274

No files matched your search

+3 -7
View File
@@ -7,6 +7,7 @@ on:
workflow_run:
workflows:
- Sync CVE PoCs
- Hot CVEs List
types:
- completed
push:
@@ -35,13 +36,8 @@ jobs:
with:
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Build site
run: python scripts/build_site.py --html-mode summary
- name: Build site data
run: python3 scripts/build_site.py
- name: Configure Pages
uses: actions/configure-pages@v6
+1 -5
View File
@@ -18,8 +18,6 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v7
@@ -40,13 +38,11 @@ jobs:
.github/cve_sync_state.json \
github.txt \
references.txt \
docs/CVE_list.json \
':(top,glob)[12][0-9][0-9][0-9]/CVE-*.md'
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "Update CVE PoCs $(date -u +'%Y-%m-%d')"
git pull --rebase origin main
git push origin main
git push origin HEAD:main
fi
+2
View File
@@ -1,4 +1,6 @@
data/
.venv/
docs/CVE_list.json
docs/trending_poc.json
docs/api/v1/cve/
__pycache__/
-1
View File
@@ -1 +0,0 @@
[{"cve": "CVE-2026-0006", "desc": "In multiple locations, there is a possible out of bounds read and write due to a heap buffer overflow. This could lead to remote code execution with no additional execution privileges needed. User interaction is not needed for exploitation.", "poc": ["https://github.com/aydin5245/cve-2026-0006", "https://github.com/mobilehackinglab/CVE-2026-0006-openapv-poc"]}, {"cve": "CVE-2026-0013", "desc": "In setupLayout of PickActivity.java, there is a possible way to start any activity as a DocumentsUI app due to a confused deputy. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.", "poc": ["https://github.com/inforcqb/cve-2026-0013-exploit", "https://github.com/XiaoBaiLovesStirring/cve-2026-0013-poc"]}, {"cve": "CVE-2026-0023", "desc": "In createSessionInternal of PackageInstallerService.java, there is a possible way for an app to update its ownership due to a missing permission check. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.", "poc": ["https://github.com/QM4RS/CVE-2026-0023-Update-Ownership-PoC"]}, {"cve": "CVE-2026-0047", "desc": "In dumpBitmapsProto of ActivityManagerService.java, there is a possible way for an app to access private information due to a missing permission check. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.", "poc": ["https://github.com/mobilehackinglab/CVE-2026-0047-poc"]}, {"cve": "CVE-2026-0049", "desc": "In onHeaderDecoded of LocalImageResolver.java, there is a possible persistent denial of service due to resource exhaustion. This could lead to local denial of service with no additional execution privileges needed. User interaction is not needed for exploitation.", "poc": ["https://github.com/R3n3r0/CVE-2026-0049"]}, {"cve": "CVE-2026-0059", "desc": "In multiple functions of sdp_discovery.cc, there is a possible way to achieve code execution due to a heap buffer overflow. This could lead to remote (proximal/adjacent) code execution with no additional execution privileges needed. User interaction is not needed for exploitation.", "poc": ["https://github.com/paul-goon/bootlicka-POC"]}, {"cve": "CVE-2026-0073", "desc": "In adbd_tls_verify_cert of auth.cpp, there is a possible bypass of wireless ADB mutual authentication due to a logic error in the code. This could lead to remote (proximal/adjacent) code execution as the shell user with no additional execution privileges needed. User interaction is not needed for exploitation.", "poc": ["https://github.com/SecTestAnnaQuinn/CVE-2026-0073-Android-adbd-authentication-bypass-POC", "https://github.com/adityatelange/poc-CVE-2026-0073", "https://github.com/MartinPSDev/CVE-2026-0073-Android-ADBD-bypass-POC", "https://github.com/0xBlackash/CVE-2026-0073", "https://github.com/novaek/CVE-2026-0073-Research", "https://github.com/unnaim/adbHijacker", "https://github.com/xqi1337/poc-CVE-2026-0073", "https://github.com/ctn-Qvo/CVE-2026-0073-Android-ADBD-bypass-POC_zh_CN", "https://github.com/m00ddy/CVE-2026-0073-Android-client-TLS-auth-bypass", "https://github.com/fredevsec/CVE-2026-0073", "https://github.com/aye468448-eng/CVE-2026-0073-Android-adbd-authentication-bypass"]}, {"cve": "CVE-2026-0092", "desc": "In Package Manager, there is a possible device lock controller bypass due to a missing permission check. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.", "poc": ["https://github.com/Majorjayyy1/CVE-2026-0092"]}, {"cve": "CVE-2026-0163", "desc": "In multiple functions of vpu_ioctl.c, there is a possible use after free due to a use after free. This could lead to remote escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.", "poc": ["https://github.com/sentinel-aidefense/CVE-2026-0163-EXP"]}, {"cve": "CVE-2026-0227", "desc": "A vulnerability in Palo Alto Networks PAN-OS software enables an unauthenticated attacker to cause a denial of service (DoS) to the firewall. Repeated attempts to trigger this issue results in the firewall entering into maintenance mode.", "poc": ["https://github.com/TeeyaR/CVE-2026-0227-Palo-Alto"]}, {"cve": "CVE-2026-0257", "desc": "Authentication bypass vulnerabilities in the GlobalProtect portal and gateway of Palo Alto Networks PAN-OS® software allows the attacker to bypass security restrictions and establish an unauthorized VPN connection.\nPanorama and Cloud NGFW are not impacted by these issues.", "poc": ["https://github.com/sfewer-r7/CVE-2026-0257", "https://github.com/0xBlackash/CVE-2026-0257", "https://github.com/tushargurav28/CVE-2026-0257", "https://github.com/akashsingh0454/CVE-2026-0257-PoC", "https://github.com/Mr-Robot-LP/CVE-2Line truncated
-150
View File
@@ -1,150 +0,0 @@
#!/usr/bin/python3
import json
import os
import re
from pathlib import Path
from typing import Collection, Dict, List, Optional, Tuple
from urllib.parse import urlparse
ROOT = Path(__file__).resolve().parent.parent
OUTPUT = Path(__file__).resolve().with_name("CVE_list.json")
BLACKLIST = ROOT / "blacklist.txt"
def load_blacklist(path: Path = BLACKLIST) -> set[str]:
if not path.exists():
return set()
items: set[str] = set()
for raw in path.read_text(encoding="utf-8").splitlines():
entry = raw.strip()
if entry and not entry.startswith("#"):
items.add(entry.lower())
return items
def repo_from_url(url: str) -> str:
try:
parsed = urlparse(url)
host = (parsed.netloc or "").lower()
if host and "github" not in host:
return ""
path = parsed.path or url
except Exception:
path = url
parts = path.strip("/").split("/")
if len(parts) >= 2:
return "/".join(parts[:2]).lower()
return (parts[-1] if parts else "").lower()
def is_blacklisted(url: str, blacklist: Collection[str]) -> bool:
full_name = repo_from_url(url)
if not full_name:
return False
return full_name in blacklist
def link_key(url: str) -> str:
parsed = urlparse(url)
if (parsed.hostname or "").lower() not in {"github.com", "www.github.com"}:
return url
parts = [part for part in parsed.path.split("/") if part]
if len(parts) < 2:
return url
repo = f"{parts[0]}/{parts[1]}".lower()
suffix = "/" + "/".join(parts[2:]) if len(parts) > 2 else ""
return f"github:{repo}{suffix}?{parsed.query}#{parsed.fragment}"
def normalise_block(text: str) -> str:
text = text.replace("\r\n", "\n")
text = re.sub(r"\n{2,}", "\n", text.strip())
lines = [line.lstrip("- ").rstrip() for line in text.split("\n")]
return "\n".join(line for line in lines if line)
def parse_sections(content: str) -> Dict[str, str]:
sections: Dict[str, str] = {}
current_header: str | None = None
buffer: List[str] = []
for line in content.splitlines():
header = line.strip()
if header.startswith("### ") or header.startswith("#### "):
if current_header is not None:
sections[current_header] = "\n".join(buffer).strip()
current_header = header
buffer = []
else:
buffer.append(line)
if current_header is not None:
sections[current_header] = "\n".join(buffer).strip()
return sections
def collect_links(block: str, *, blacklist: Optional[Collection[str]] = None) -> List[str]:
links: List[str] = []
blacklist = blacklist or set()
for raw in block.splitlines():
entry = raw.strip()
if not entry or "No PoCs" in entry:
continue
if entry.startswith("- "):
entry = entry[2:].strip()
if not entry:
continue
if is_blacklisted(entry, blacklist):
continue
if entry not in links:
links.append(entry)
return links
def main() -> None:
blacklist = load_blacklist()
cve_entries = []
years = [entry for entry in os.listdir(ROOT) if entry.isdigit()]
years.sort(reverse=True)
for year in years:
year_dir = ROOT / year
for filename in sorted(os.listdir(year_dir)):
if not filename.endswith(".md"):
continue
with open(year_dir / filename, "r", encoding="utf-8") as handle:
content = handle.read()
sections = parse_sections(content)
description = normalise_block(sections.get("### Description", ""))
references = collect_links(sections.get("#### Reference", ""), blacklist=blacklist)
github_links = collect_links(sections.get("#### Github", ""), blacklist=blacklist)
poc_entries: List[str] = []
seen = set()
for link in references + github_links:
key = link_key(link)
if key not in seen:
poc_entries.append(link)
seen.add(key)
cve_id = filename.replace(".md", "")
# Skip CVEs with zero PoCs (both sections empty) to keep lookup clean
if not poc_entries:
continue
cve_entries.append({
"cve": cve_id,
"desc": description,
"poc": poc_entries,
})
with open(OUTPUT, "w", encoding="utf-8") as outfile:
json.dump(cve_entries, outfile, ensure_ascii=False)
print("CVE list saved to CVE_list.json")
if __name__ == "__main__":
main()
+164 -3
View File
@@ -1,4 +1,165 @@
{
"generated": "2025-12-18T00:00:00Z",
"items": []
}
"generated": "2026-08-30T14:55:32.061796+00:00",
"items": [
{
"year": 2026,
"stars": 4056,
"updated": "2 hours ago",
"name": "copy-fail-CVE-2026-31431",
"url": "https://github.com/theori-io/copy-fail-CVE-2026-31431",
"desc": "Copy Fail (CVE-2026-31431): 9-year-old Linux kernel LPE found by Theori's Xint Code"
},
{
"year": 2026,
"stars": 571,
"updated": "3 days ago",
"name": "cve_2026_31431",
"url": "https://github.com/rootsecdev/cve_2026_31431",
"desc": "Exploit POC for CVE_2026_31431"
},
{
"year": 2026,
"stars": 325,
"updated": "2 days ago",
"name": "CVE-2026-54121",
"url": "https://github.com/aniqfakhrul/CVE-2026-54121",
"desc": "Certighost POC"
},
{
"year": 2026,
"stars": 531,
"updated": "2 days ago",
"name": "cve-2026-41940-PoC",
"url": "https://github.com/lanicer/cve-2026-41940-PoC",
"desc": "A cPanel and WHM authentication bypassing tool"
},
{
"year": 2026,
"stars": 235,
"updated": "1 hour ago",
"name": "CVE-2026-43499-popsicle",
"url": "https://github.com/x-spy/CVE-2026-43499-popsicle",
"desc": "CVE-2026-43499 Implementation for 6.12.23-android16-5-g75e9b1c7ae7c-abogki463945075-4k"
},
{
"year": 2026,
"stars": 212,
"updated": "5 days ago",
"name": "CVE-2026-41089",
"url": "https://github.com/0xABCD01/CVE-2026-41089",
"desc": "CVE-2026-41089 PoC — Netlogon CLDAP stack buffer overflow (CVSS 9.8 CRITICAL)"
},
{
"year": 2026,
"stars": 260,
"updated": "1 day ago",
"name": "CVE-2026-21858",
"url": "https://github.com/Chocapikk/CVE-2026-21858",
"desc": "n8n Ni8mare - Unauthenticated Arbitrary File Read to RCE Chain (CVSS 10.0)"
},
{
"year": 2026,
"stars": 262,
"updated": "7 hours ago",
"name": "CVE-2026-40369-EXPLOIT",
"url": "https://github.com/orinimron123/CVE-2026-40369-EXPLOIT",
"desc": "Full exploit code for CVE-2026-40369 - A Windows kernel arbitrary write vulnerability that allows browser sandbox escape from all browsers render process sandbox"
},
{
"year": 2026,
"stars": 207,
"updated": "5 days ago",
"name": "CVE-2026-24061",
"url": "https://github.com/SafeBreach-Labs/CVE-2026-24061",
"desc": "Exploitation of CVE-2026-24061"
},
{
"year": 2026,
"stars": 154,
"updated": "6 days ago",
"name": "CVE-2026-43499",
"url": "https://github.com/MobiusM/CVE-2026-43499",
"desc": "CVE-2026-43499 PoC"
},
{
"year": 2026,
"stars": 824,
"updated": "1 day ago",
"name": "CVE-2026-24061",
"url": "https://github.com/jacubes/CVE-2026-24061",
"desc": "CVE-2026-24061 exploit PoC"
},
{
"year": 2026,
"stars": 146,
"updated": "58 minutes ago",
"name": "CVE-2026-62911",
"url": "https://github.com/hypnguyen1209/CVE-2026-62911",
"desc": "POC pre-auth RCE on Exchange"
},
{
"year": 2026,
"stars": 128,
"updated": "11 days ago",
"name": "CVE-2026-20817",
"url": "https://github.com/oxfemale/CVE-2026-20817",
"desc": "Windows Error Reporting ALPC Elevation of Privilege (CVE-2026-20817) - Proof-of-Concept exploit demonstrating local privilege escalation via WER service."
},
{
"year": 2026,
"stars": 77,
"updated": "7 hours ago",
"name": "CVE-2026-75604-poc",
"url": "https://github.com/rafabd1/CVE-2026-75604-poc",
"desc": "CVE-2026-75604 Next.js Windows RCE poc"
},
{
"year": 2026,
"stars": 100,
"updated": "5 days ago",
"name": "CVE-2026-42980-POC",
"url": "https://github.com/G4sp4rCS/CVE-2026-42980-POC",
"desc": "CVE-2026-42980 PUBLIC EXPLOIT + RESEARCH"
},
{
"year": 2026,
"stars": 111,
"updated": "1 hour ago",
"name": "CVE-2026-31431-Advanced-Exploit",
"url": "https://github.com/Sndav/CVE-2026-31431-Advanced-Exploit",
"desc": "CVE-2026-31431 纯文件利用"
},
{
"year": 2026,
"stars": 119,
"updated": "1 hour ago",
"name": "CVE-2026-41651",
"url": "https://github.com/Vozec/CVE-2026-41651",
"desc": ""
},
{
"year": 2026,
"stars": 18,
"updated": "2 days ago",
"name": "CVE-2026-43499-Poc-Analysis",
"url": "https://github.com/xianwan1314/CVE-2026-43499-Poc-Analysis",
"desc": "Vulnerability analysis and Proof of Concept (PoC) for CVE-2026-43499 affecting Xiaomi devices. For educational and research purposes only."
},
{
"year": 2026,
"stars": 63,
"updated": "4 days ago",
"name": "CVE-2026-45504",
"url": "https://github.com/hawktrace/CVE-2026-45504",
"desc": "CVE-2026-45504 Microsoft Exchange File Read"
},
{
"year": 2026,
"stars": 80,
"updated": "2 days ago",
"name": "CVE-2026-43499-Poc-Analysis",
"url": "https://github.com/Linuxoid-cn/CVE-2026-43499-Poc-Analysis",
"desc": "Vulnerability analysis and Proof of Concept (PoC) for CVE-2026-43499 affecting Xiaomi devices. For educational and research purposes only."
}
]
}
-2
View File
@@ -1,3 +1 @@
requests
jinja2
python-dateutil
+3 -30
View File
@@ -8,9 +8,7 @@ from pathlib import Path
from typing import Collection, Dict, List, Optional
from urllib.parse import urlparse
from jinja2 import Environment, FileSystemLoader, select_autoescape
from utils import DOCS_DIR, TEMPLATES_DIR, ensure_dirs, load_blacklist, parse_trending_from_readme, is_blacklisted_repo
from utils import DOCS_DIR, ensure_dirs, load_blacklist, parse_trending_from_readme, is_blacklisted_repo
ROOT = DOCS_DIR.parent
README_PATH = ROOT / "README.md"
@@ -18,20 +16,6 @@ CVE_OUTPUT = DOCS_DIR / "CVE_list.json"
TRENDING_OUTPUT = DOCS_DIR / "trending_poc.json"
def build_env() -> Environment:
loader = FileSystemLoader(str(TEMPLATES_DIR))
env = Environment(loader=loader, autoescape=select_autoescape(["html", "xml"]))
env.trim_blocks = True
env.lstrip_blocks = True
return env
def render(env: Environment, template_name: str, context: Dict, output_path: Path) -> None:
html = env.get_template(template_name).render(**context)
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(html, encoding="utf-8")
def normalise_block(text: str) -> str:
text = text.replace("\r\n", "\n")
text = re.sub(r"\n{2,}", "\n", text.strip())
@@ -184,14 +168,7 @@ def write_json(path: Path, data, *, indent: Optional[int] = None) -> None:
def main() -> int:
parser = argparse.ArgumentParser(description="Build CVE PoC site")
parser.add_argument(
"--html-mode",
choices=["none", "summary", "all"],
default="summary",
help="Render HTML or skip it.",
)
args = parser.parse_args()
argparse.ArgumentParser(description="Build the CVE PoC site data files").parse_args()
ensure_dirs(DOCS_DIR)
blacklist = load_blacklist()
@@ -209,11 +186,7 @@ def main() -> int:
indent=2,
)
if args.html_mode != "none":
env = build_env()
render(env, "index.html", {"trending": trending_items}, DOCS_DIR / "index.html")
print("Site generated under docs/")
print(f"Wrote {CVE_OUTPUT.name} ({len(cve_payload)} CVEs) and {TRENDING_OUTPUT.name}")
return 0
+2 -3
View File
@@ -6,8 +6,6 @@ from datetime import datetime, timezone
from pathlib import Path
from typing import Collection, Dict, Iterable, List, Optional, Tuple
import requests
ROOT = Path(__file__).resolve().parents[1]
DATA_DIR = ROOT / "data"
DOCS_DIR = ROOT / "docs"
@@ -15,7 +13,6 @@ API_DIR = DOCS_DIR / "api" / "v1"
SNAPSHOT_DIR = API_DIR / "snapshots"
DIFFS_DIR = API_DIR / "diffs"
TOP_DIR = API_DIR / "top"
TEMPLATES_DIR = ROOT / "templates"
ASSETS_DIR = DOCS_DIR / "assets"
CACHE_DIR = DATA_DIR / "cache"
STATE_DIR = DATA_DIR / "state"
@@ -41,6 +38,8 @@ def save_json(path: Path, data, *, sort_keys: bool = True) -> None:
def fetch_json(url: str, *, timeout: int = 30, headers: Optional[Dict[str, str]] = None):
import requests
response = requests.get(url, timeout=timeout, headers=headers or {})
response.raise_for_status()
return response.json()
-16
View File
@@ -1,16 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ title or 'CVE PoC Hub' }}</title>
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="/style.css" />
</head>
<body class="{{ body_class or '' }}">
<main class="wrap">
{% block content %}{% endblock %}
</main>
{% block extra_scripts %}{% endblock %}
</body>
</html>
-57
View File
@@ -1,57 +0,0 @@
{% extends "base.html" %}
{% set body_class = "color-no-search" %}
{% block content %}
<section class="hero" data-search-root>
<h1>CVE PoC Hub</h1>
<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>
<form class="searchForm" action="#">
<input type="text" class="search" placeholder="Search CVE, vendor, product, or keyword" autocomplete="off">
</form>
<div class="search-results" data-results style="display:none">
<div class="header">
<h2>Results</h2>
</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" data-trending-section>
<h2>Recently updated Proof-of-Concepts</h2>
<div class="table-wrap" data-trending>
<table>
<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>{{ 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="4">No recent PoCs.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</section>
{% endblock %}
{% block extra_scripts %}
<script src="/logic.js"></script>
{% endblock %}