A focused hardening release addressing findings from a full security and code review. No user-facing feature changes; the tool behaves the same, but is meaningfully more robust against abuse and operates more reliably.
All application JavaScript was moved out of index.html into an external app.js, which let us remove 'unsafe-inline' from the script-src CSP directive. Inline script injection is now blocked by the browser as a defense-in-depth layer behind the existing output escaping.
Added an HTTP Strict-Transport-Security (HSTS) header and a proxy-aware HTTP→HTTPS redirect (keyed off X-Forwarded-Proto to avoid redirect loops behind the CloudWays load balancer).
The exploit-intelligence endpoint no longer persists database rows or writes import-log entries for CVEs that return no data from any upstream source. This prevents arbitrary, well-formed CVE IDs from filling tables and draining the shared NVD/EPSS rate budget.
The per-IP rate limiter now uses exclusive file locking for its read-modify-write cycle, closing a race condition (TOCTOU) where concurrent requests could collectively exceed the configured limit.
Requests to the POST logging endpoint that present neither an Origin nor a Referer header are now rejected (modern browsers always send Origin on state-changing requests).
Closed several defense-in-depth gaps where trusted-but-external values (NVD score/severity, CISA KEV CWE identifiers, database severity strings) were interpolated into HTML/attributes without escaping. The OTX pulse_count is now cast to an integer server-side.
The data-update cron invoked api/import-epss-csv.php and api/download-mitre-attack.php, but those scripts live in scripts/. The full-history EPSS import (which powers the complete LEV calculation) and the MITRE refresh were silently failing; both paths are corrected.
Consolidated the cron script's filesystem paths under a single APP_ROOT variable (previously a mix of /mnt/data/home/... and /home/... that relied on a symlink).
The hourly cron now prunes dated EPSS/NVD snapshot files older than 30 days and clears stale per-IP rate-limit files, preventing unbounded disk growth.
Exploit intelligence served via the real-time API fallback (rather than the pre-computed CSV) is now flagged as (partial), since the fallback does not query every exploit repository.
The "Learn more about LEV" link pointed to a NIST URL that no longer resolves. It now links to the locally hosted NIST CSWP 41 PDF.
Clicking "Copy Results" did nothing for CVEs that have no exploit-intelligence data (e.g. brand-new CVEs) due to a null-reference error in the copy-text builder. Also hardened the clipboard logic: it now detects a secure context, prefers the modern Clipboard API, falls back gracefully (with iOS handling), and shows a clear "Copy failed" state instead of failing silently.
app.js file must be deployed alongside index.html.Fixed issue where the "Search history enabled/disabled" toggle icon remained fixed at the top of the screen while scrolling through results.
Added threat-enhanced CVSS scoring that factors in real-world exploit availability, powered by data from CVSS-TE project.
Visual indicators showing which exploit repositories have weaponized code for the CVE:
Added VulnCheck KEV indicator as an alternative to CISA KEV for broader exploit awareness.
Pre-computed scores from daily CSV import with real-time API fallback for missing CVEs.
Independent CVSS-TE calculation using quality multipliers, threat intelligence factors, and time decay - no dependency on external updates.
api/exploit-intel.php - Exploit intelligence API endpointscripts/import-cvss-te.php - Daily CSV import cron jobapi/schema.sql - New exploit_intel and exploit_intel_log tables0 3 * * * php /path/to/scripts/import-cvss-te.phpFixed issue where CVEs not found in AlienVault OTX (404 responses) were not being cached properly, causing repeated API calls.
Added improved error logging for OTX API failures to aid debugging.
All database queries now use parameterized prepared statements. Batch imports use single prepared statement with transactions.
Updated getClientIp() to validate X-Forwarded-For only from trusted proxies.
CVE input limited to 13-30 characters to prevent ReDoS attacks on validation regex.
Added validation functions for EPSS, NVD, and threat actor API responses to safely handle malformed data.
Added normalizeMalwareName() to prevent bypass via Unicode tricks or special characters.
Users can now disable localStorage search history tracking via a privacy toggle.
CVEs in CISA KEV with knownRansomwareCampaignUse: "Known" now display a prominent ransomware badge, making it immediately visible when a vulnerability has been used in ransomware campaigns.
When a CVE is found in CISA KEV, the following additional fields are now displayed:
The "Copy Results" feature now includes all new KEV enrichment fields for easy sharing.
escapeHtml() function to sanitize external data before rendering, preventing potential XSS from malicious KEV data.Reorganized and updated the external API documentation in the footer to clearly list all data sources used by the tool:
Added acknowledgment to the original project that inspired this tool:
See which APT groups, ransomware operators, and botnets have exploited a specific CVE, powered by AlienVault Open Threat Exchange (OTX) community threat intelligence.
Threat actors are enriched with detailed profiles from MITRE ATT&CK including aliases, country attribution, and technique descriptions.
Visual indicator when a CVE is associated with nation-state sponsored threat actors.
Shows how many community threat intelligence "pulses" reference the CVE - indicating level of threat actor interest.
Implemented singleton pattern with persistent PDO connections to reduce connection overhead.
MITRE ATT&CK and CISA KEV data now cached in memory after first load, eliminating redundant file I/O.
Replaced O(n) loops with hash map indexes for MITRE actor lookups (by name/alias) and CISA KEV checks.
OTX API results cached in database for 24 hours to reduce external API calls. Supports ?refresh=1 to bypass cache.
api/threat-actors.php - Threat actor intelligence endpoint (AlienVault OTX + MITRE enrichment)api/config.php - Updated with OTX API configuration and optimized helper functionsscripts/download-mitre-attack.php - MITRE ATT&CK data downloaderdata/mitre-attack/ - Local cache for MITRE ATT&CK threat actor profilesapi/config.php for higher rate limits.scripts/download-mitre-attack.php initially.Added LEV (Likely Exploited Vulnerabilities) scoring based on NIST CSWP 41 - a backward-looking cumulative exploitation probability metric.
New dedicated section displaying LEV Score, Composite Probability, data coverage period, and calculation source indicator.
Track how many users searched for each CVE on the site over time.
Line chart showing EPSS score changes over the past 30 days.
scope=time-series endpointPrevious chart instances are now properly destroyed before creating new ones, preventing memory buildup during repeated lookups.
The tool now checks for CVSS 4.0 metrics in addition to 3.1 and 3.0, ensuring newer vulnerabilities display correct severity scores.
Corrected the URL in copied results from "epsslook.com" to "epsslookuptool.com".
Decreased the cooldown between lookups from 10 seconds to 3 seconds for faster consecutive searches.
Moved Chart.js script to end of body with defer attribute to improve initial page load time.
Added 5-minute client-side caching for lookup results. Cached results display instantly with a "Cached" badge indicator.
All API calls (EPSS, NVD, KEV, LEV, Search Stats) now execute concurrently for faster results.
Added animated spinner with "Fetching vulnerability data..." message during API calls for better user feedback.
Added clickable history chips showing up to 10 recent CVE lookups, stored in localStorage and persisted across sessions.
Repositioned tooltips on mobile devices to prevent overflow and improve readability.
Added Ctrl+Enter (or Cmd+Enter on Mac) to submit the lookup form from anywhere on the page.
api/lev.php - LEV calculation endpointapi/log-search.php - Search logging endpointapi/search-stats.php - Search statistics endpointapi/schema.sql - Database schema for search tracking and EPSS historyapi/import-epss-csv.php - EPSS data importer for full LEV calculationcisa-kev/download_cisa_kev.sh - Now downloads EPSS CSVapi/config.php.Modified the CISA KEV reference link to point to the specific CVE record on CVE.org instead of the general CISA KEV catalog page.
https://www.cisa.gov/known-exploited-vulnerabilities-catalog) to a dynamic link using the CVE number (e.g., https://www.cve.org/CVERecord?id=CVE-2025-22457).None introduced in this update.
Added the "Due Date" field to the results for CVEs found in the CISA KEV catalog, showing the remediation deadline (e.g., "2022-01-10"). Displays "N/A" if the due date is not available.
dueDate from the matching KEV entry in the cached data.Optimized performance by caching the CISA KEV data on page load and reusing it for subsequent lookups.
cisaKevCache object to store the data, last fetch timestamp, and a Set of CVE IDs for O(1) lookups.Removed dependency on CORS proxies by hosting the CISA KEV JSON file locally, updated hourly via a cron job.
https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json every hour.Improved readability by widening the display and enlarging the radar chart.
.container max-width from 500px to 800px.Resolved an issue where CISA KEV status was incorrectly showing "Unknown" due to CORS fetch failures.
.loading CSS class for the loading indicator during initial CISA KEV fetch.curl or Node.js script) to download the CISA KEV file hourly.Modified the footer layout to place the "Changelog" link on a new line below the "Data provided by" line.
tags for better visual separation.|) as it was no longer needed with the new layout.Added a check for whether a CVE is in the CISA KEV catalog, displaying "Yes" with a reference link or "No".
https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json.None introduced in this update.
Added a "Copy Results" button to the output section, allowing users to copy vulnerability details in a report-friendly text format.
navigator.clipboard API for modern browsers, with a fallback for older browsers using a temporary textarea.Users can now easily paste results into reports, emails, or other documents, improving workflow efficiency.
None introduced in this update.
.copy-button CSS class to style the new button consistently with the existing design.Added functionality to accept a CVE ID from the URL query string (e.g., epsslook.com/?cve=CVE-2055-123456) to auto-populate the input field and trigger a lookup.
getQueryParam(param) function to parse URL query parameters.DOMContentLoaded event listener to extract, validate, and submit the CVE.Expanded search result output to include additional vulnerability details from the NVD API:
These fields are conditionally rendered when NVD data is available, enhancing context for users.
None introduced in this update.
Initial implementation of URL query parameter parsing and auto-submission (as detailed in v1.2.0).
Released prior to adding enhanced result details.
Initial release with: