Add eol_check.py — lifecycle / End-of-Life intel tool (endoflife.date, pure-stdlib)#91
Open
venkatas wants to merge 1 commit into
Open
Add eol_check.py — lifecycle / End-of-Life intel tool (endoflife.date, pure-stdlib)#91venkatas wants to merge 1 commit into
venkatas wants to merge 1 commit into
Conversation
…date Pure-stdlib recon/intel tool: maps detected tech fingerprints to endoflife.date product slugs and reports whether each release is supported, security-only, nearing EOL, in extended/ESM support, or past EOL. Complements CVE lookup with a factual, verifiable finding (unsupported software = no security patches). Design principle: prefer 'indeterminate' over guessing. An unmatched, absent, or malformed version yields 'unknown' — the tool never classifies an install from an unrelated release and never emits [CONFIRMED] it cannot substantiate. - Confidence tags: past-EOL -> [CONFIRMED]; EOL-soon / extended-support -> [POSSIBLE]; supported / security-only / unknown -> [INFORMATIONAL]. - String-based cycle matching on canonical identifiers (handles v-prefixed and patch-level versions; refuses ambiguous / duplicate / mixed-identifier matches). - Distinguishes standard EOL from extended/ESM support (reads support + eol + extendedSupport) so ESM-covered releases aren't overstated as 'no fixes'. - Slugs validated against /api/all.json; ambiguous fingerprints (iis, bare powershell, generic java/openjdk) omitted rather than mapped to a wrong product; vendor-specific JDKs (temurin/corretto/zulu/oracle) resolve precisely. - Hardened against malformed/hostile data: rejects control/format/separator chars (by Unicode category) in identifiers, requires canonical dates, validates payload types, bounds response + cache size, sanitizes slugs (no path traversal) and output, fails soft on every I/O / parse / cache path. - CLI exit codes: 2 = a CONFIRMED past-EOL item; 3 = --strict + indeterminate; 1 = requested --json artifact could not be written. - 58 deterministic tests (network mocked; dates relative so nothing rots). Credit: lifecycle data from endoflife.date (MIT).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this adds
tools/eol_check.py— a small, pure-stdlib recon/intel tool that maps a target'sdetected tech fingerprints to endoflife.date product slugs and
reports the lifecycle status of each release: supported, security-only, EOL-soon,
extended/ESM support, or past-EOL. Past-EOL software is a factual, verifiable finding
(unsupported = no security patches), so this complements CVE lookup during recon.
Why it fits the repo
urllib/json/ssl) — nothing to install, so it can never be the"missing dependency" that skips a scan. Drops into
tools/alongside the other Python tools.[CONFIRMED]/[POSSIBLE]/[INFORMATIONAL].~/.cache/bughunter/eol), so repeat runs are free.Design principle: prefer "indeterminate" over guessing
A lifecycle checker that guesses is worse than useless in a security context. So:
unknown— the tool never classifies aninstall from an unrelated release, and never emits
[CONFIRMED]it can't substantiate.support+eol+extendedSupport), so an ESM-covered release (e.g. Ubuntu 20.04 → 2030) is reported as[POSSIBLE] extended, not[CONFIRMED] no fixes.v-prefixed andpatch-level versions and refuses ambiguous / mixed-identifier matches (e.g. won't match
an AWS-Lambda
nodejs18.xruntime against aruby4.0cycle)./api/all.json; genuinely ambiguous fingerprints(
iis, barepowershell) are omitted rather than mapped to a wrong product.Safety / robustness (hardened against malformed / hostile data)
in any identifier, so a malformed cycle id or version can't be
str.strip()-canonicalizedinto a false match; requires canonical
YYYY-MM-DDdates so a non-schema date can'tsubstantiate a verdict.
unknowninstead of crashing on anon-list / rate-limit / truncated body), only matches string cycle ids, treats duplicate
or ambiguous cycles as indeterminate, and downgrades a past-EOL record whose extended/ESM
support can't be ruled out to
[POSSIBLE]rather than[CONFIRMED].size, dedups fetches per run, and fails soft on every I/O / parse / cache-write path.
NO_COLOR+ non-TTY aware; strips terminal control characters from rendered output andfrom the
--jsonartifact.2= a[CONFIRMED]past-EOL item is present;3=--strictand something was indeterminate (lets CI tell "checked, fine" from"couldn't check");
1= a requested--jsonartifact could not be written; else0.Tests
tests/test_eol_check.py— 58 deterministic tests (network mocked; all dates builtrelative to "today" so nothing rots). Covers the no-fabrication contract, version matching
edge cases (v-prefix, patch-level, boundary, mixed/duplicate identifiers, Unicode-separator
rejection), extended/security-support semantics, malformed-payload and crash robustness,
slug + output sanitization, dedup, and CLI exit codes.
The tool was hardened across several adversarial review passes specifically to ensure it
prefers "indeterminate" over ever emitting an unsubstantiated
[CONFIRMED]finding.Notes
endoflife.dateREST endpoint. A future enhancement could move to/api/v1/products/{product}to consume its nativeisEoas/isMaintainedfields.retained in both the tool output and the JSON export.