mirror of
https://github.com/0xMarcio/cve.git
synced 2026-10-27 16:51:03 +00:00
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:
1 parent
b1ac17daf9
commit
f9fc5ae28d
11 files changed
+175
-274
No files matched your search
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1,4 +1,6 @@
|
||||
data/
|
||||
.venv/
|
||||
docs/CVE_list.json
|
||||
docs/trending_poc.json
|
||||
docs/api/v1/cve/
|
||||
__pycache__/
|
||||
@@ -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
|
||||
@@ -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
@@ -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."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,3 +1 @@
|
||||
requests
|
||||
jinja2
|
||||
python-dateutil
|
||||
+3
-30
@@ -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
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
@@ -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 %}
|
||||
Reference in new issue
Block a user