Commit Graph
6 Commits
Author SHA1 Message Date
vulncheck dbad9a365e chore(rebrand): VulnCheck → TrueVuln
Renames the product name in every user-visible surface and internal
self-reference: page title, nav/shell, login/MFA pages, email templates and
subject prefixes ([VULNCHECK] → [TRUEVULN]), TOTP issuer label, report/PDF
headers, notification previews, outbound User-Agent/HTTP-Referer headers we
set ourselves, docs (README, ARCHITECTURE, PROJECT_OVERVIEW, DATABASE_SCHEMA,
README.DEV, TROUBLESHOOTING is untouched — see below), and .env.example
placeholder config (LDAP/OIDC/SAML example domains and paths).

Also renamed the on-disk cache file paths (/tmp/vulncheck-*.zip|csv|json →
/tmp/truevuln-*), kept consistent across the two files that share the
cvelistV5 ZIP cache path — first run after deploy re-downloads that ~557 MB
cache once (harmless, disposable).

Deliberately LEFT UNCHANGED (not branding — real external references or
infra identifiers; renaming the text without renaming the underlying thing
would just break/mislead):
- The actual Gitea repo URL/path (gitea.isuit.ch/vulncheck/vulncheck) and the
  README lines derived from it (git clone target dir, tree listing) — a real
  repo rename is a manual Gitea-side step (Settings → repository name) the
  user would need to do themselves, and existing clones would need
  `git remote set-url` after.
- The real support mailbox (support-vulncheck.sq9vd@passmail.net, in both
  README and TROUBLESHOOTING) and the Buy Me A Coffee link — both point to
  accounts that still exist under the old name; renaming the text alone
  wouldn't create new ones.
- GitNexus MCP resource URIs in CLAUDE.md/AGENTS.md (gitnexus://repo/
  vulncheck/...) — tied to GitNexus's own index name for this repo, not our
  branding; those files are untracked in this repo anyway.
- docker-compose.yml container/network/Postgres user+db names
  (vulnmanager-*) — explicit user decision: infra naming carries real
  deploy/data risk on an already-running instance and isn't part of the
  product-branding ask.
- The Tailwind color token class `vulncheck-blue` (frontend/app/globals.css)
  — invisible internal CSS variable name, renaming it would touch ~270
  className occurrences for zero user-visible benefit.

Verified: backend py_compile clean on every touched .py file; frontend tsc
clean (two pre-existing, unrelated errors remain: assets/page.tsx SVG title
prop, mfa-setup missing qrcode.react types). All diffs are exact-string
renames — no other changes riding along.
2026-07-07 16:34:40 +02:00
vulncheck 7425d79453 feat(android): Samsung SMR as primary source, ASB as fallback; fix stale cache
1. Samsung SMR precision (tester's point 1): security.samsungmobile.com's
   yearly page (?year=YYYY) serves ALL ~12 months' content server-side in the
   raw HTML — the accordion is pure CSS/JS, it doesn't gate what's delivered
   — so it IS reliably parseable per month, contrary to what I assumed
   earlier. New samsung_smr_service parses each SMR-MMM-YYYY block: Google
   Critical/High CVEs MINUS the "Not applicable to Samsung devices" list,
   plus Samsung Semiconductor Critical/High fixes. Cached per year (24h).

   android_cve_service.check_android_cves now takes `manufacturer`: Samsung
   devices try the SMR month first (source 'samsung-smr'), falling back to
   raw ASB (source 'android-asb') only when SMR doesn't cover that month or
   the fetch fails. Non-Samsung Android stays on ASB. This directly fixes
   the false positive the tester hit: CVE-2025-59604 (Qualcomm-only) is
   explicitly "Not applicable to Samsung devices" on Samsung's own page and
   is now excluded — verified against the live page (absent from the parsed
   June-2026 set).

2. Cache bug (tester's point 2): a device stuck showing only the newest
   month's CVEs despite older months (verified live: 2025-09 had 59, 2025-12
   had 57 AOSP critical/high CVEs) turned out to be stale cache entries from
   before today's URL-format and SoC-section-filter fixes — the "non-empty is
   immutable" cache rule kept serving pre-fix (empty or wrong) data forever.
   Bumped _CACHE_PREFIX (asb_month_v2_) so every month is refetched under the
   current, correct logic.

Both parsers verified against live data (JS + Python) before shipping:
19 months of Samsung SMR (2025-01–2026-07) parsed without error with
plausible per-month counts; ASB severity counts confirmed non-zero and
variable across all 12 lookback months.
2026-07-07 13:30:55 +02:00
vulncheck f645cadc7b fix(android-asb): only import AOSP CVEs, skip chipset/SoC vendor sections
Raw ASB import created false positives on Samsung (and any) devices: ASB
lists chipset-vendor CVEs (Qualcomm/MediaTek/Unisoc/Imagination/Arm) that
only affect devices with that SoC — Samsung's own SMR marks many "Not
applicable to Samsung devices". The parser now walks section headers + rows
in order and keeps only the AOSP sections (Framework/System/Kernel/Runtime/
Media/Google Play/Widevine) that apply to any Android device at that patch
level; SoC/vendor sections are dropped.

Verified on 2025-09: 115 total → 59 AOSP kept, ~49 SoC dropped; the Framework
KEV CVE-2025-48543 is retained.

(Samsung's own page can't scope per-device either without JS — it loads
month bodies via AJAX — so AOSP-section filtering is the robust fix. Samsung-
proprietary SVE CVEs remain out of scope.)
2026-07-05 17:00:08 +02:00
vulncheck 101445109f fix: ASB 2026 URL format, cvelistV5 fixed_version, macOS OS-CVE scan
- android-asb: from 2026 Google nests the bulletin under a year segment
  (/bulletin/2026/2026-01-01); older months stay flat (/bulletin/2025-10-01).
  fetch_asb_month now tries the year-nested URL first, then flat. Verified:
  2026-01 → nested 200/flat 404; 2025-xx → nested 404/flat 200.
- cvelistV5 scan: stop using lessThanOrEqual as fixed_version — that bound
  means the version is still affected (no published fix), so leave
  fixed_version empty (correct "no patch available", e.g. 7-Zip CVE-2026-58052
  ≤26.02). Only lessThan is a real fix target.
- app-cve OS scan: add macOS (cpe:2.3:o:apple:macos) alongside iOS/iPadOS so
  Mac assets get OS CVEs (e.g. Apple CVE-2026-43700, previously only Defender
  saw it).
2026-07-05 16:54:50 +02:00
vulncheck 59e4afbeb3 fix(android-asb): negative-cache empty/404 months to stop the refetch storm
Future ASB months Google hasn't published yet return 404. fetch_asb_month
only cached successful months, so every Android device re-fetched the same
404 months on every sync (the tester saw 2026-01…06 hammered dozens of times).

Now empty/404 results are cached too, with a 3-day TTL: months with CVEs stay
immutable/cached forever; empty months are skipped for 3 days, then retried
so a newly-published month is picked up. Legacy list-format cache entries
still read correctly.

(The 404s are expected — those months aren't published on source.android.com
yet; the 2025 months that exist already produced android-asb findings.)
2026-07-05 16:51:53 +02:00
vulncheck ed78810ad8 feat(intune): per-CVE Android detection from Google ASB
For Intune-managed Android devices, raise real-CVE findings for the months
the device is behind on patches. Device patch level (androidSecurityPatchLevel,
e.g. 2025-03-01) → every monthly Android Security Bulletin published after it
lists CVEs the device hasn't received. Fetched from source.android.com
(stable, static, per-month) and parsed (CVE + severity, severity carried
across rowspan rows); cached per month in a Setting.

Source 'android-asb' (real CVE ids → EPSS/KEV/CVSS enrichment applies). Wired
into the Intune sync alongside the patch-level-staleness headline finding.

Why not Samsung's SMR page: securityUpdate.smsb ignores the year/month query
param and loads the month via JS — a plain fetch returns the same latest month
regardless (verified: 2025-03/-04/-09 all identical). ASB is the upstream
source for the Google CVEs Samsung ships (the security-critical bulk).
Samsung-proprietary SVE CVEs aren't covered (their page is unscrapeable).

Volume guards: Critical + High only, last 12 months (tunable via _MAX_MONTHS
/ _WANT_SEV). Verified month math + the ASB parser against the live bulletins
(2025-09 → 109 CVEs, per-month distinct).
2026-06-30 10:48:06 +02:00