diff --git a/08-threat-intel/generated/source-health.json b/08-threat-intel/generated/source-health.json index d6aa5935..0be49cc5 100644 --- a/08-threat-intel/generated/source-health.json +++ b/08-threat-intel/generated/source-health.json @@ -1,16 +1,17 @@ { - "generated_at": "2026-03-18T21:09:25+00:00", - "active_source_count": 125, - "green_source_count": 125, + "generated_at": "2026-03-19T00:21:33+00:00", + "active_source_count": 118, + "green_source_count": 118, "failure_count": 0, "all_green": true, - "last_fully_green_run": "2026-03-18T21:09:25+00:00", + "last_fully_green_run": "2026-03-19T00:21:33+00:00", "retries_performed": 0, "probes": [ { "system_id": "adminer", "source_name": "NVD Adminer", "source_kind": "nvd-search", + "elapsed_seconds": 4.829, "kind": "nvd-search", "items_seen": 1 }, @@ -18,6 +19,7 @@ "system_id": "adobe-commerce", "source_name": "Adobe Magento Security Index", "source_kind": "vendor-index", + "elapsed_seconds": 1.246, "kind": "vendor-index", "items_seen": 46 }, @@ -25,6 +27,7 @@ "system_id": "adobe-commerce", "source_name": "NVD Adobe Commerce", "source_kind": "nvd-search", + "elapsed_seconds": 0.952, "kind": "nvd-search", "items_seen": 1 }, @@ -32,6 +35,7 @@ "system_id": "angular", "source_name": "OSV Angular", "source_kind": "osv-batch", + "elapsed_seconds": 3.751, "kind": "osv-batch", "items_seen": 1 }, @@ -39,6 +43,7 @@ "system_id": "apache-httpd", "source_name": "Apache HTTPD Security", "source_kind": "html-links", + "elapsed_seconds": 4.638, "kind": "html-links", "items_seen": 182 }, @@ -46,6 +51,7 @@ "system_id": "apache-httpd", "source_name": "CISA KEV Apache HTTPD", "source_kind": "kev-json", + "elapsed_seconds": 5.0, "kind": "kev-json", "items_seen": 1545 }, @@ -53,6 +59,7 @@ "system_id": "apache-httpd", "source_name": "NVD Apache HTTP Server", "source_kind": "nvd-search", + "elapsed_seconds": 4.349, "kind": "nvd-search", "items_seen": 1 }, @@ -60,6 +67,7 @@ "system_id": "apache-tomcat", "source_name": "Apache Tomcat Security", "source_kind": "html-links", + "elapsed_seconds": 4.994, "kind": "html-links", "items_seen": 270 }, @@ -67,6 +75,7 @@ "system_id": "apache-tomcat", "source_name": "CISA KEV Tomcat", "source_kind": "kev-json", + "elapsed_seconds": 5.127, "kind": "kev-json", "items_seen": 1545 }, @@ -74,6 +83,7 @@ "system_id": "apache-tomcat", "source_name": "NVD Tomcat", "source_kind": "nvd-search", + "elapsed_seconds": 4.52, "kind": "nvd-search", "items_seen": 1 }, @@ -81,6 +91,7 @@ "system_id": "aspnet-core", "source_name": "NVD ASP.NET Core", "source_kind": "nvd-search", + "elapsed_seconds": 3.974, "kind": "nvd-search", "items_seen": 1 }, @@ -88,6 +99,7 @@ "system_id": "astro", "source_name": "OSV Astro", "source_kind": "osv-batch", + "elapsed_seconds": 3.947, "kind": "osv-batch", "items_seen": 1 }, @@ -95,6 +107,7 @@ "system_id": "caddy", "source_name": "GitHub Caddy Advisories", "source_kind": "html-links", + "elapsed_seconds": 5.38, "kind": "html-links", "items_seen": 114 }, @@ -102,6 +115,7 @@ "system_id": "caddy", "source_name": "OSV Caddy", "source_kind": "osv-batch", + "elapsed_seconds": 5.422, "kind": "osv-batch", "items_seen": 1 }, @@ -109,6 +123,7 @@ "system_id": "directus", "source_name": "Directus GitHub Advisories", "source_kind": "html-links", + "elapsed_seconds": 1.22, "kind": "html-links", "items_seen": 127 }, @@ -116,6 +131,7 @@ "system_id": "directus", "source_name": "OSV Directus", "source_kind": "osv-batch", + "elapsed_seconds": 0.977, "kind": "osv-batch", "items_seen": 1 }, @@ -123,6 +139,7 @@ "system_id": "discourse", "source_name": "Discourse Release Notes RSS", "source_kind": "rss-feed", + "elapsed_seconds": 1.863, "kind": "rss-feed", "items_seen": 30 }, @@ -130,6 +147,7 @@ "system_id": "discourse", "source_name": "Discourse Security RSS", "source_kind": "rss-feed", + "elapsed_seconds": 1.413, "kind": "rss-feed", "items_seen": 3 }, @@ -137,6 +155,7 @@ "system_id": "discourse", "source_name": "OSV Discourse", "source_kind": "osv-batch", + "elapsed_seconds": 1.671, "kind": "osv-batch", "items_seen": 1 }, @@ -144,6 +163,7 @@ "system_id": "django", "source_name": "Django Security Releases Archive", "source_kind": "vendor-index", + "elapsed_seconds": 4.637, "kind": "vendor-index", "items_seen": 1276 }, @@ -151,6 +171,7 @@ "system_id": "django", "source_name": "Django Security Weblog", "source_kind": "vendor-index", + "elapsed_seconds": 4.824, "kind": "vendor-index", "items_seen": 332 }, @@ -158,6 +179,7 @@ "system_id": "django", "source_name": "OSV Django", "source_kind": "osv-batch", + "elapsed_seconds": 6.118, "kind": "osv-batch", "items_seen": 1 }, @@ -165,48 +187,39 @@ "system_id": "drupal", "source_name": "Drupal Security Advisories RSS", "source_kind": "rss-feed", + "elapsed_seconds": 1.032, "kind": "rss-feed", "items_seen": 20 }, { "system_id": "drupal", - "source_name": "NVD Drupal", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV Drupal", + "source_kind": "osv-batch", + "elapsed_seconds": 1.868, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "echo", "source_name": "OSV Echo", "source_kind": "osv-batch", + "elapsed_seconds": 4.99, "kind": "osv-batch", "items_seen": 1 }, - { - "system_id": "esbuild", - "source_name": "NVD esbuild", - "source_kind": "nvd-search", - "kind": "nvd-search", - "items_seen": 0 - }, { "system_id": "esbuild", "source_name": "OSV esbuild", "source_kind": "osv-batch", + "elapsed_seconds": 4.069, "kind": "osv-batch", "items_seen": 1 }, - { - "system_id": "express", - "source_name": "NVD Express.js", - "source_kind": "nvd-search", - "kind": "nvd-search", - "items_seen": 1 - }, { "system_id": "express", "source_name": "OSV Express", "source_kind": "osv-batch", + "elapsed_seconds": 3.751, "kind": "osv-batch", "items_seen": 1 }, @@ -214,6 +227,7 @@ "system_id": "fastify", "source_name": "OSV Fastify", "source_kind": "osv-batch", + "elapsed_seconds": 3.946, "kind": "osv-batch", "items_seen": 1 }, @@ -221,6 +235,7 @@ "system_id": "flask", "source_name": "OSV Flask", "source_kind": "osv-batch", + "elapsed_seconds": 4.906, "kind": "osv-batch", "items_seen": 1 }, @@ -228,20 +243,23 @@ "system_id": "ghost", "source_name": "Ghost GitHub Advisories", "source_kind": "html-links", + "elapsed_seconds": 1.0, "kind": "html-links", "items_seen": 119 }, { "system_id": "ghost", - "source_name": "NVD Ghost", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV Ghost", + "source_kind": "osv-batch", + "elapsed_seconds": 1.324, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "gin", "source_name": "OSV Gin", "source_kind": "osv-batch", + "elapsed_seconds": 4.992, "kind": "osv-batch", "items_seen": 1 }, @@ -249,6 +267,7 @@ "system_id": "gitea", "source_name": "GitHub Gitea Advisories", "source_kind": "html-links", + "elapsed_seconds": 5.673, "kind": "html-links", "items_seen": 98 }, @@ -256,6 +275,7 @@ "system_id": "gitea", "source_name": "OSV Gitea", "source_kind": "osv-batch", + "elapsed_seconds": 6.049, "kind": "osv-batch", "items_seen": 1 }, @@ -263,6 +283,7 @@ "system_id": "gitlab-ce", "source_name": "GitLab Advisory Database", "source_kind": "html-links", + "elapsed_seconds": 6.042, "kind": "html-links", "items_seen": 5 }, @@ -270,6 +291,7 @@ "system_id": "gitlab-ce", "source_name": "GitLab Security Releases", "source_kind": "html-links", + "elapsed_seconds": 6.673, "kind": "html-links", "items_seen": 250 }, @@ -277,6 +299,7 @@ "system_id": "gitlab-ce", "source_name": "NVD GitLab", "source_kind": "nvd-search", + "elapsed_seconds": 4.992, "kind": "nvd-search", "items_seen": 1 }, @@ -284,6 +307,7 @@ "system_id": "grafana", "source_name": "CISA KEV Grafana", "source_kind": "kev-json", + "elapsed_seconds": 5.651, "kind": "kev-json", "items_seen": 1545 }, @@ -291,6 +315,7 @@ "system_id": "grafana", "source_name": "Grafana Security Advisories", "source_kind": "html-links", + "elapsed_seconds": 5.894, "kind": "html-links", "items_seen": 159 }, @@ -298,6 +323,7 @@ "system_id": "hapi", "source_name": "OSV Hapi", "source_kind": "osv-batch", + "elapsed_seconds": 3.84, "kind": "osv-batch", "items_seen": 1 }, @@ -305,6 +331,7 @@ "system_id": "haproxy", "source_name": "HAProxy Blog Feed", "source_kind": "rss-feed", + "elapsed_seconds": 6.563, "kind": "rss-feed", "items_seen": 10 }, @@ -312,6 +339,7 @@ "system_id": "haproxy", "source_name": "NVD HAProxy", "source_kind": "nvd-search", + "elapsed_seconds": 4.638, "kind": "nvd-search", "items_seen": 1 }, @@ -319,6 +347,7 @@ "system_id": "jenkins", "source_name": "Jenkins Security Advisories", "source_kind": "html-links", + "elapsed_seconds": 5.749, "kind": "html-links", "items_seen": 1194 }, @@ -326,6 +355,7 @@ "system_id": "jenkins", "source_name": "NVD Jenkins", "source_kind": "nvd-search", + "elapsed_seconds": 4.993, "kind": "nvd-search", "items_seen": 1 }, @@ -333,20 +363,23 @@ "system_id": "joomla", "source_name": "Joomla Security Centre", "source_kind": "html-links", + "elapsed_seconds": 1.895, "kind": "html-links", "items_seen": 139 }, { "system_id": "joomla", - "source_name": "NVD Joomla", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV Joomla", + "source_kind": "osv-batch", + "elapsed_seconds": 0.931, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "kibana", "source_name": "Elastic Security Announcements", "source_kind": "html-links", + "elapsed_seconds": 5.942, "kind": "html-links", "items_seen": 82 }, @@ -354,6 +387,7 @@ "system_id": "kibana", "source_name": "NVD Kibana", "source_kind": "nvd-search", + "elapsed_seconds": 5.109, "kind": "nvd-search", "items_seen": 1 }, @@ -361,6 +395,7 @@ "system_id": "koa", "source_name": "OSV Koa", "source_kind": "osv-batch", + "elapsed_seconds": 3.947, "kind": "osv-batch", "items_seen": 1 }, @@ -368,6 +403,7 @@ "system_id": "laravel", "source_name": "OSV Laravel", "source_kind": "osv-batch", + "elapsed_seconds": 4.829, "kind": "osv-batch", "items_seen": 1 }, @@ -375,6 +411,7 @@ "system_id": "magento-open-source", "source_name": "Magento GitHub Advisories", "source_kind": "html-links", + "elapsed_seconds": 1.87, "kind": "html-links", "items_seen": 99 }, @@ -382,6 +419,7 @@ "system_id": "magento-open-source", "source_name": "NVD Magento", "source_kind": "nvd-search", + "elapsed_seconds": 0.97, "kind": "nvd-search", "items_seen": 1 }, @@ -389,6 +427,7 @@ "system_id": "magento-open-source", "source_name": "Sansec Research", "source_kind": "html-links", + "elapsed_seconds": 2.585, "kind": "html-links", "items_seen": 134 }, @@ -396,34 +435,39 @@ "system_id": "mattermost", "source_name": "Mattermost Security Updates JSON", "source_kind": "json-feed", + "elapsed_seconds": 6.41, "kind": "json-feed", "items_seen": 594 }, { "system_id": "mattermost", - "source_name": "NVD Mattermost", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV Mattermost", + "source_kind": "osv-batch", + "elapsed_seconds": 7.189, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "mediawiki", "source_name": "MediaWiki Announce RSS", "source_kind": "rss-feed", + "elapsed_seconds": 2.9, "kind": "rss-feed", "items_seen": 30 }, { "system_id": "mediawiki", - "source_name": "NVD MediaWiki", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV MediaWiki", + "source_kind": "osv-batch", + "elapsed_seconds": 1.445, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "medusa", "source_name": "GitHub Medusa Advisories", "source_kind": "html-links", + "elapsed_seconds": 2.902, "kind": "html-links", "items_seen": 102 }, @@ -431,27 +475,23 @@ "system_id": "medusa", "source_name": "OSV Medusa", "source_kind": "osv-batch", + "elapsed_seconds": 2.809, "kind": "osv-batch", "items_seen": 1 }, { "system_id": "moodle", - "source_name": "NVD Moodle", - "source_kind": "nvd-search", - "kind": "nvd-search", - "items_seen": 1 - }, - { - "system_id": "nestjs", - "source_name": "NVD NestJS", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV Moodle", + "source_kind": "osv-batch", + "elapsed_seconds": 4.14, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "nestjs", "source_name": "OSV NestJS", "source_kind": "osv-batch", + "elapsed_seconds": 3.748, "kind": "osv-batch", "items_seen": 1 }, @@ -459,6 +499,7 @@ "system_id": "nextjs", "source_name": "GitHub Next.js Advisories", "source_kind": "html-links", + "elapsed_seconds": 2.906, "kind": "html-links", "items_seen": 123 }, @@ -466,6 +507,7 @@ "system_id": "nextjs", "source_name": "OSV Next.js", "source_kind": "osv-batch", + "elapsed_seconds": 3.107, "kind": "osv-batch", "items_seen": 1 }, @@ -473,6 +515,7 @@ "system_id": "nginx", "source_name": "CISA KEV NGINX", "source_kind": "kev-json", + "elapsed_seconds": 5.108, "kind": "kev-json", "items_seen": 1545 }, @@ -480,6 +523,7 @@ "system_id": "nginx", "source_name": "NGINX Security Advisories", "source_kind": "html-links", + "elapsed_seconds": 5.603, "kind": "html-links", "items_seen": 138 }, @@ -487,6 +531,7 @@ "system_id": "nginx", "source_name": "NVD NGINX", "source_kind": "nvd-search", + "elapsed_seconds": 4.069, "kind": "nvd-search", "items_seen": 1 }, @@ -494,6 +539,7 @@ "system_id": "nodejs", "source_name": "CISA KEV Node.js", "source_kind": "kev-json", + "elapsed_seconds": 3.759, "kind": "kev-json", "items_seen": 1545 }, @@ -501,6 +547,7 @@ "system_id": "nodejs", "source_name": "Node.js Security Releases", "source_kind": "html-links", + "elapsed_seconds": 4.007, "kind": "html-links", "items_seen": 74 }, @@ -508,6 +555,7 @@ "system_id": "nuxt", "source_name": "Nuxt Security", "source_kind": "html-links", + "elapsed_seconds": 3.299, "kind": "html-links", "items_seen": 118 }, @@ -515,48 +563,55 @@ "system_id": "nuxt", "source_name": "OSV Nuxt", "source_kind": "osv-batch", + "elapsed_seconds": 3.434, "kind": "osv-batch", "items_seen": 1 }, { "system_id": "opencart", - "source_name": "NVD OpenCart", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV OpenCart", + "source_kind": "osv-batch", + "elapsed_seconds": 2.893, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "opencart", "source_name": "OpenCart Releases", "source_kind": "html-links", + "elapsed_seconds": 3.545, "kind": "html-links", "items_seen": 1500 }, { "system_id": "openmage", - "source_name": "NVD OpenMage", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV OpenMage", + "source_kind": "osv-batch", + "elapsed_seconds": 1.922, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "openmage", "source_name": "OpenMage GitHub Advisories", "source_kind": "html-links", + "elapsed_seconds": 1.897, "kind": "html-links", "items_seen": 125 }, { "system_id": "phpmyadmin", - "source_name": "NVD phpMyAdmin", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV phpMyAdmin", + "source_kind": "osv-batch", + "elapsed_seconds": 6.445, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "phpmyadmin", "source_name": "phpMyAdmin Security Page", "source_kind": "html-links", + "elapsed_seconds": 5.517, "kind": "html-links", "items_seen": 262 }, @@ -564,6 +619,7 @@ "system_id": "prestashop", "source_name": "Friends Of Presta Security", "source_kind": "html-links", + "elapsed_seconds": 2.735, "kind": "html-links", "items_seen": 38 }, @@ -571,34 +627,31 @@ "system_id": "prestashop", "source_name": "GitHub PrestaShop Advisories", "source_kind": "html-links", + "elapsed_seconds": 2.426, "kind": "html-links", "items_seen": 127 }, { "system_id": "prestashop", - "source_name": "NVD PrestaShop", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV PrestaShop", + "source_kind": "osv-batch", + "elapsed_seconds": 2.895, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "prestashop", "source_name": "PrestaShop Security Page", "source_kind": "html-links", + "elapsed_seconds": 2.37, "kind": "html-links", "items_seen": 60 }, - { - "system_id": "rails", - "source_name": "NVD Ruby on Rails", - "source_kind": "nvd-search", - "kind": "nvd-search", - "items_seen": 1 - }, { "system_id": "rails", "source_name": "OSV Rails", "source_kind": "osv-batch", + "elapsed_seconds": 4.99, "kind": "osv-batch", "items_seen": 1 }, @@ -606,6 +659,7 @@ "system_id": "react", "source_name": "GitHub React Advisories", "source_kind": "html-links", + "elapsed_seconds": 2.904, "kind": "html-links", "items_seen": 110 }, @@ -613,20 +667,15 @@ "system_id": "react", "source_name": "OSV React", "source_kind": "osv-batch", + "elapsed_seconds": 3.121, "kind": "osv-batch", "items_seen": 1 }, - { - "system_id": "redmine", - "source_name": "NVD Redmine", - "source_kind": "nvd-search", - "kind": "nvd-search", - "items_seen": 1 - }, { "system_id": "redmine", "source_name": "Redmine Security Advisories", "source_kind": "html-links", + "elapsed_seconds": 7.087, "kind": "html-links", "items_seen": 371 }, @@ -634,27 +683,31 @@ "system_id": "saleor", "source_name": "GitHub Saleor Advisories", "source_kind": "html-links", + "elapsed_seconds": 2.743, "kind": "html-links", "items_seen": 120 }, { "system_id": "saleor", - "source_name": "NVD Saleor", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV Saleor", + "source_kind": "osv-batch", + "elapsed_seconds": 2.894, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "shopware", - "source_name": "NVD Shopware", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV Shopware", + "source_kind": "osv-batch", + "elapsed_seconds": 3.031, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "shopware", "source_name": "Shopware Security Advisories", "source_kind": "html-links", + "elapsed_seconds": 2.569, "kind": "html-links", "items_seen": 129 }, @@ -662,6 +715,7 @@ "system_id": "spring-boot", "source_name": "OSV Spring Boot", "source_kind": "osv-batch", + "elapsed_seconds": 4.636, "kind": "osv-batch", "items_seen": 1 }, @@ -669,6 +723,7 @@ "system_id": "spring-boot", "source_name": "Spring Security Advisories", "source_kind": "html-links", + "elapsed_seconds": 4.349, "kind": "html-links", "items_seen": 118 }, @@ -676,6 +731,7 @@ "system_id": "spring-framework", "source_name": "OSV Spring Framework", "source_kind": "osv-batch", + "elapsed_seconds": 4.525, "kind": "osv-batch", "items_seen": 1 }, @@ -683,6 +739,7 @@ "system_id": "spring-framework", "source_name": "Spring Security Advisories", "source_kind": "html-links", + "elapsed_seconds": 4.378, "kind": "html-links", "items_seen": 118 }, @@ -690,6 +747,7 @@ "system_id": "spring-security", "source_name": "OSV Spring Security", "source_kind": "osv-batch", + "elapsed_seconds": 4.519, "kind": "osv-batch", "items_seen": 1 }, @@ -697,6 +755,7 @@ "system_id": "spring-security", "source_name": "Spring Security Advisories", "source_kind": "html-links", + "elapsed_seconds": 4.535, "kind": "html-links", "items_seen": 118 }, @@ -704,6 +763,7 @@ "system_id": "strapi", "source_name": "OSV Strapi", "source_kind": "osv-batch", + "elapsed_seconds": 0.954, "kind": "osv-batch", "items_seen": 1 }, @@ -711,6 +771,7 @@ "system_id": "strapi", "source_name": "Strapi GitHub Advisories", "source_kind": "html-links", + "elapsed_seconds": 0.973, "kind": "html-links", "items_seen": 124 }, @@ -718,6 +779,7 @@ "system_id": "sveltekit", "source_name": "OSV SvelteKit", "source_kind": "osv-batch", + "elapsed_seconds": 4.068, "kind": "osv-batch", "items_seen": 1 }, @@ -725,6 +787,7 @@ "system_id": "symfony", "source_name": "OSV Symfony", "source_kind": "osv-batch", + "elapsed_seconds": 5.516, "kind": "osv-batch", "items_seen": 1 }, @@ -732,6 +795,7 @@ "system_id": "traefik", "source_name": "GitHub Traefik Advisories", "source_kind": "html-links", + "elapsed_seconds": 5.515, "kind": "html-links", "items_seen": 124 }, @@ -739,20 +803,15 @@ "system_id": "traefik", "source_name": "OSV Traefik", "source_kind": "osv-batch", + "elapsed_seconds": 5.601, "kind": "osv-batch", "items_seen": 1 }, - { - "system_id": "undici", - "source_name": "NVD Undici", - "source_kind": "nvd-search", - "kind": "nvd-search", - "items_seen": 1 - }, { "system_id": "undici", "source_name": "OSV Undici", "source_kind": "osv-batch", + "elapsed_seconds": 3.974, "kind": "osv-batch", "items_seen": 1 }, @@ -760,6 +819,7 @@ "system_id": "vite", "source_name": "OSV Vite", "source_kind": "osv-batch", + "elapsed_seconds": 3.751, "kind": "osv-batch", "items_seen": 1 }, @@ -767,6 +827,7 @@ "system_id": "vite", "source_name": "Vite Security", "source_kind": "html-links", + "elapsed_seconds": 3.553, "kind": "html-links", "items_seen": 124 }, @@ -774,6 +835,7 @@ "system_id": "vue", "source_name": "OSV Vue", "source_kind": "osv-batch", + "elapsed_seconds": 3.312, "kind": "osv-batch", "items_seen": 1 }, @@ -781,20 +843,15 @@ "system_id": "vue", "source_name": "Vue Security", "source_kind": "html-links", + "elapsed_seconds": 3.226, "kind": "html-links", "items_seen": 111 }, - { - "system_id": "webpack", - "source_name": "NVD webpack", - "source_kind": "nvd-search", - "kind": "nvd-search", - "items_seen": 1 - }, { "system_id": "webpack", "source_name": "OSV webpack", "source_kind": "osv-batch", + "elapsed_seconds": 4.274, "kind": "osv-batch", "items_seen": 1 }, @@ -802,6 +859,7 @@ "system_id": "werkzeug", "source_name": "OSV Werkzeug", "source_kind": "osv-batch", + "elapsed_seconds": 4.989, "kind": "osv-batch", "items_seen": 1 }, @@ -809,20 +867,23 @@ "system_id": "woocommerce", "source_name": "GitHub WooCommerce Advisories", "source_kind": "html-links", + "elapsed_seconds": 2.243, "kind": "html-links", "items_seen": 107 }, { "system_id": "woocommerce", - "source_name": "NVD WooCommerce", - "source_kind": "nvd-search", - "kind": "nvd-search", + "source_name": "OSV WooCommerce", + "source_kind": "osv-batch", + "elapsed_seconds": 2.036, + "kind": "osv-batch", "items_seen": 1 }, { "system_id": "woocommerce", "source_name": "Patchstack Database", "source_kind": "html-links", + "elapsed_seconds": 2.046, "kind": "html-links", "items_seen": 193 }, @@ -830,6 +891,7 @@ "system_id": "woocommerce", "source_name": "Woo Developer Advisories", "source_kind": "html-links", + "elapsed_seconds": 1.563, "kind": "html-links", "items_seen": 121 }, @@ -837,6 +899,7 @@ "system_id": "woocommerce", "source_name": "Wordfence Vulnerability Database", "source_kind": "html-links", + "elapsed_seconds": 1.854, "kind": "html-links", "items_seen": 0 }, @@ -844,6 +907,7 @@ "system_id": "wordpress", "source_name": "NVD WordPress", "source_kind": "nvd-search", + "elapsed_seconds": 0.005, "kind": "nvd-search", "items_seen": 1 }, @@ -851,6 +915,7 @@ "system_id": "wordpress", "source_name": "Patchstack Database", "source_kind": "html-links", + "elapsed_seconds": 1.666, "kind": "html-links", "items_seen": 193 }, @@ -858,6 +923,7 @@ "system_id": "wordpress", "source_name": "PortSwigger Research", "source_kind": "html-links", + "elapsed_seconds": 1.863, "kind": "html-links", "items_seen": 99 }, @@ -865,6 +931,7 @@ "system_id": "wordpress", "source_name": "WPScan Vulnerability Database", "source_kind": "html-links", + "elapsed_seconds": 1.38, "kind": "html-links", "items_seen": 74 }, @@ -872,6 +939,7 @@ "system_id": "wordpress", "source_name": "WordPress Security News", "source_kind": "html-links", + "elapsed_seconds": 2.182, "kind": "html-links", "items_seen": 138 }, @@ -879,11 +947,84 @@ "system_id": "wordpress", "source_name": "Wordfence Vulnerability Database", "source_kind": "html-links", + "elapsed_seconds": 0.879, "kind": "html-links", "items_seen": 0 } ], "failures": [], + "slow_sources": [ + { + "system_id": "mattermost", + "source_name": "OSV Mattermost", + "source_kind": "osv-batch", + "elapsed_seconds": 7.189, + "status": "ok" + }, + { + "system_id": "redmine", + "source_name": "Redmine Security Advisories", + "source_kind": "html-links", + "elapsed_seconds": 7.087, + "status": "ok" + }, + { + "system_id": "gitlab-ce", + "source_name": "GitLab Security Releases", + "source_kind": "html-links", + "elapsed_seconds": 6.673, + "status": "ok" + }, + { + "system_id": "haproxy", + "source_name": "HAProxy Blog Feed", + "source_kind": "rss-feed", + "elapsed_seconds": 6.563, + "status": "ok" + }, + { + "system_id": "phpmyadmin", + "source_name": "OSV phpMyAdmin", + "source_kind": "osv-batch", + "elapsed_seconds": 6.445, + "status": "ok" + }, + { + "system_id": "mattermost", + "source_name": "Mattermost Security Updates JSON", + "source_kind": "json-feed", + "elapsed_seconds": 6.41, + "status": "ok" + }, + { + "system_id": "django", + "source_name": "OSV Django", + "source_kind": "osv-batch", + "elapsed_seconds": 6.118, + "status": "ok" + }, + { + "system_id": "gitea", + "source_name": "OSV Gitea", + "source_kind": "osv-batch", + "elapsed_seconds": 6.049, + "status": "ok" + }, + { + "system_id": "gitlab-ce", + "source_name": "GitLab Advisory Database", + "source_kind": "html-links", + "elapsed_seconds": 6.042, + "status": "ok" + }, + { + "system_id": "kibana", + "source_name": "Elastic Security Announcements", + "source_kind": "html-links", + "elapsed_seconds": 5.942, + "status": "ok" + } + ], "systems": [ { "system_id": "adminer", @@ -979,15 +1120,15 @@ { "system_id": "esbuild", "display_name": "esbuild", - "active_source_total": 2, - "green_source_total": 2, + "active_source_total": 1, + "green_source_total": 1, "failure_count": 0 }, { "system_id": "express", "display_name": "Express", - "active_source_total": 2, - "green_source_total": 2, + "active_source_total": 1, + "green_source_total": 1, "failure_count": 0 }, { @@ -1126,8 +1267,8 @@ { "system_id": "nestjs", "display_name": "NestJS", - "active_source_total": 2, - "green_source_total": 2, + "active_source_total": 1, + "green_source_total": 1, "failure_count": 0 }, { @@ -1189,8 +1330,8 @@ { "system_id": "rails", "display_name": "Ruby on Rails", - "active_source_total": 2, - "green_source_total": 2, + "active_source_total": 1, + "green_source_total": 1, "failure_count": 0 }, { @@ -1203,8 +1344,8 @@ { "system_id": "redmine", "display_name": "Redmine", - "active_source_total": 2, - "green_source_total": 2, + "active_source_total": 1, + "green_source_total": 1, "failure_count": 0 }, { @@ -1273,8 +1414,8 @@ { "system_id": "undici", "display_name": "Undici", - "active_source_total": 2, - "green_source_total": 2, + "active_source_total": 1, + "green_source_total": 1, "failure_count": 0 }, { @@ -1294,8 +1435,8 @@ { "system_id": "webpack", "display_name": "webpack", - "active_source_total": 2, - "green_source_total": 2, + "active_source_total": 1, + "green_source_total": 1, "failure_count": 0 }, { diff --git a/08-threat-intel/source-map.yaml b/08-threat-intel/source-map.yaml index 316b4f89..bc2d19b0 100644 --- a/08-threat-intel/source-map.yaml +++ b/08-threat-intel/source-map.yaml @@ -78,6 +78,9 @@ systems: confidence: official advisory_mode: core results_per_page: 50 + status: retired + retired_reason: OSV Drupal + Drupal official RSS now cover machine-readable collection with lower cold-start latency than NVD public search. + replacement_sources: [Drupal Security Advisories RSS, OSV Drupal] ecosystem_sources: - name: Drupal Security Advisories Site kind: html-links @@ -98,8 +101,13 @@ systems: retired_reason: Unauthenticated GHSA API requests are rate-limited in daily monitoring; RSS and NVD remain active replacements. replacement_sources: [Drupal Security Advisories RSS, NVD Drupal] research_sources: [] + ecosystem_sources: + - name: OSV Drupal + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core package_names: - - ecosystem: composer + - ecosystem: Packagist name: drupal/core cpe_keys: ["drupal:drupal"] ghsa_keywords: [drupal, drupal core] @@ -129,9 +137,18 @@ systems: confidence: official advisory_mode: core results_per_page: 50 - ecosystem_sources: [] + status: retired + retired_reason: OSV Joomla CMS replaces NVD for machine-readable collection without public NVD throttling. + replacement_sources: [Joomla Security Centre, OSV Joomla] + ecosystem_sources: + - name: OSV Joomla + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] - package_names: [] + package_names: + - ecosystem: Packagist + name: joomla/joomla-cms cpe_keys: ["joomla:joomla!"] ghsa_keywords: [joomla] kev_keywords: [joomla] @@ -160,7 +177,14 @@ systems: confidence: official advisory_mode: core results_per_page: 40 - ecosystem_sources: [] + status: retired + retired_reason: OSV Ghost replaces NVD for machine-readable collection and keeps npm package alignment. + replacement_sources: [Ghost GitHub Advisories, OSV Ghost] + ecosystem_sources: + - name: OSV Ghost + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] package_names: - ecosystem: npm @@ -267,9 +291,18 @@ systems: confidence: official advisory_mode: core results_per_page: 40 - ecosystem_sources: [] + status: retired + retired_reason: MediaWiki announce RSS plus OSV MediaWiki now replace NVD for lower-latency machine-readable collection. + replacement_sources: [MediaWiki Announce RSS, OSV MediaWiki] + ecosystem_sources: + - name: OSV MediaWiki + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] - package_names: [] + package_names: + - ecosystem: Packagist + name: mediawiki/core cpe_keys: ["mediawiki:mediawiki"] ghsa_keywords: [mediawiki] kev_keywords: [mediawiki] @@ -306,9 +339,18 @@ systems: confidence: official advisory_mode: core results_per_page: 40 - ecosystem_sources: [] + status: retired + retired_reason: OSV Moodle replaces NVD for machine-readable collection while official Moodle sources remain for cross-checking. + replacement_sources: [OSV Moodle] + ecosystem_sources: + - name: OSV Moodle + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] - package_names: [] + package_names: + - ecosystem: Packagist + name: moodle/moodle cpe_keys: ["moodle:moodle"] ghsa_keywords: [moodle] kev_keywords: [moodle] @@ -504,10 +546,17 @@ systems: confidence: official advisory_mode: core results_per_page: 40 - ecosystem_sources: [] + status: retired + retired_reason: OSV OpenMage replaces NVD for machine-readable composer-aligned collection. + replacement_sources: [OpenMage GitHub Advisories, OSV OpenMage] + ecosystem_sources: + - name: OSV OpenMage + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] package_names: - - ecosystem: composer + - ecosystem: Packagist name: openmage/magento-lts cpe_keys: [] ghsa_keywords: [openmage, mage-os] @@ -543,7 +592,14 @@ systems: confidence: official advisory_mode: core results_per_page: 40 + status: retired + retired_reason: OSV WooCommerce replaces NVD for machine-readable collection while official and ecosystem advisory pages remain active. + replacement_sources: [Woo Developer Advisories, GitHub WooCommerce Advisories, OSV WooCommerce] ecosystem_sources: + - name: OSV WooCommerce + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core - name: Patchstack Database kind: html-links url: https://patchstack.com/database/ @@ -562,7 +618,7 @@ systems: package_names: - ecosystem: npm name: "@woocommerce/blocks" - - ecosystem: composer + - ecosystem: Packagist name: woocommerce/woocommerce cpe_keys: [] ghsa_keywords: [woocommerce] @@ -599,7 +655,14 @@ systems: confidence: official advisory_mode: core results_per_page: 40 + status: retired + retired_reason: OSV PrestaShop replaces NVD for machine-readable collection while official and ecosystem advisories remain active. + replacement_sources: [PrestaShop Security Page, GitHub PrestaShop Advisories, OSV PrestaShop] ecosystem_sources: + - name: OSV PrestaShop + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core - name: Friends Of Presta Security kind: html-links url: https://security.friendsofpresta.org/ @@ -609,7 +672,7 @@ systems: max_items: 50 research_sources: [] package_names: - - ecosystem: composer + - ecosystem: Packagist name: prestashop/prestashop cpe_keys: ["prestashop:prestashop"] ghsa_keywords: [prestashop] @@ -639,10 +702,17 @@ systems: confidence: official advisory_mode: core results_per_page: 40 - ecosystem_sources: [] + status: retired + retired_reason: OSV Shopware replaces NVD for machine-readable collection with lower cold-start overhead. + replacement_sources: [Shopware Security Advisories, OSV Shopware] + ecosystem_sources: + - name: OSV Shopware + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] package_names: - - ecosystem: composer + - ecosystem: Packagist name: shopware/platform cpe_keys: [] ghsa_keywords: [shopware] @@ -671,10 +741,17 @@ systems: confidence: official advisory_mode: core results_per_page: 50 - ecosystem_sources: [] + status: retired + retired_reason: OSV OpenCart replaces NVD for machine-readable collection while official release source remains active. + replacement_sources: [OpenCart Releases, OSV OpenCart] + ecosystem_sources: + - name: OSV OpenCart + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] package_names: - - ecosystem: composer + - ecosystem: Packagist name: opencart/opencart cpe_keys: ["opencart:opencart"] ghsa_keywords: [opencart] @@ -703,10 +780,17 @@ systems: confidence: official advisory_mode: core results_per_page: 40 - ecosystem_sources: [] + status: retired + retired_reason: OSV Saleor replaces NVD for machine-readable collection and aligns with the published PyPI package. + replacement_sources: [GitHub Saleor Advisories, OSV Saleor] + ecosystem_sources: + - name: OSV Saleor + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] package_names: - - ecosystem: pypi + - ecosystem: PyPI name: saleor cpe_keys: [] ghsa_keywords: [saleor] @@ -1069,6 +1153,9 @@ systems: confidence: ecosystem-authority advisory_mode: core results_per_page: 40 + status: retired + retired_reason: OSV Express replaces NVD public search for lower-latency machine-readable collection. + replacement_sources: [OSV Express] research_sources: [] package_names: - ecosystem: npm @@ -1107,6 +1194,9 @@ systems: confidence: ecosystem-authority advisory_mode: core results_per_page: 40 + status: retired + retired_reason: OSV NestJS replaces NVD public search for lower-latency machine-readable collection. + replacement_sources: [OSV NestJS] research_sources: [] package_names: - ecosystem: npm @@ -1271,6 +1361,9 @@ systems: confidence: ecosystem-authority advisory_mode: core results_per_page: 40 + status: retired + retired_reason: OSV Undici replaces NVD public search for lower-latency machine-readable collection. + replacement_sources: [OSV Undici] research_sources: [] package_names: - ecosystem: npm @@ -1309,6 +1402,9 @@ systems: confidence: ecosystem-authority advisory_mode: core results_per_page: 40 + status: retired + retired_reason: OSV webpack replaces NVD public search for lower-latency machine-readable collection. + replacement_sources: [OSV webpack] research_sources: [] package_names: - ecosystem: npm @@ -1347,6 +1443,9 @@ systems: confidence: ecosystem-authority advisory_mode: core results_per_page: 40 + status: retired + retired_reason: OSV esbuild replaces NVD public search for lower-latency machine-readable collection. + replacement_sources: [OSV esbuild] research_sources: [] package_names: - ecosystem: npm @@ -1687,6 +1786,9 @@ systems: confidence: ecosystem-authority advisory_mode: core results_per_page: 40 + status: retired + retired_reason: OSV Rails replaces NVD public search for lower-latency machine-readable collection. + replacement_sources: [OSV Rails] research_sources: [] package_names: - ecosystem: RubyGems @@ -1995,7 +2097,14 @@ systems: confidence: official advisory_mode: core results_per_page: 40 - ecosystem_sources: [] + status: retired + retired_reason: OSV phpMyAdmin replaces NVD for machine-readable collection while the official security page remains active. + replacement_sources: [phpMyAdmin Security Page, OSV phpMyAdmin] + ecosystem_sources: + - name: OSV phpMyAdmin + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] package_names: - ecosystem: Packagist @@ -2211,6 +2320,9 @@ systems: confidence: official advisory_mode: core results_per_page: 40 + status: retired + retired_reason: Mattermost official JSON feed plus OSV Mattermost replace NVD for lower-latency machine-readable collection. + replacement_sources: [Mattermost Security Updates JSON, OSV Mattermost] - name: Mattermost Security Updates JSON kind: json-feed url: https://securityupdates.mattermost.com/security_updates.json @@ -2219,9 +2331,15 @@ systems: max_items: 600 request_policy: accept: application/json - ecosystem_sources: [] + ecosystem_sources: + - name: OSV Mattermost + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] - package_names: [] + package_names: + - ecosystem: Go + name: github.com/mattermost/mattermost-server cpe_keys: ["mattermost:mattermost"] ghsa_keywords: [mattermost] kev_keywords: [mattermost] @@ -2249,7 +2367,14 @@ systems: confidence: official advisory_mode: core results_per_page: 40 - ecosystem_sources: [] + status: retired + retired_reason: Official Redmine advisories page remains active and NVD public search is retired to reduce cold-start latency. + replacement_sources: [Redmine Security Advisories] + ecosystem_sources: + - name: OSV Redmine + kind: osv-batch + confidence: ecosystem-authority + advisory_mode: core research_sources: [] package_names: - ecosystem: RubyGems diff --git a/scripts/intel/monitoring.py b/scripts/intel/monitoring.py index 61af95ab..d7fdb543 100644 --- a/scripts/intel/monitoring.py +++ b/scripts/intel/monitoring.py @@ -206,6 +206,37 @@ def build_source_health_snapshot( all_green = not normalized_failures previous = previous or {} last_fully_green_run = generated_at if all_green else previous.get("last_fully_green_run") + slow_sources = [] + telemetry_rows = [] + for probe in probes: + if probe.get("elapsed_seconds") is None: + continue + telemetry_rows.append( + { + "system_id": probe["system_id"], + "source_name": probe["source_name"], + "source_kind": probe.get("source_kind"), + "elapsed_seconds": probe.get("elapsed_seconds"), + "status": "ok", + } + ) + for failure in normalized_failures: + if failure.get("elapsed_seconds") is None: + continue + telemetry_rows.append( + { + "system_id": failure["system_id"], + "source_name": failure["source_name"], + "source_kind": failure.get("source_kind"), + "elapsed_seconds": failure.get("elapsed_seconds"), + "status": failure.get("category") or "failure", + } + ) + slow_sources = sorted( + telemetry_rows, + key=lambda item: float(item.get("elapsed_seconds") or 0), + reverse=True, + )[:10] return { "generated_at": generated_at, "active_source_count": active_source_total, @@ -216,6 +247,7 @@ def build_source_health_snapshot( "retries_performed": retries_performed, "probes": sorted(probes, key=lambda item: (item["system_id"], item["source_name"])), "failures": normalized_failures, + "slow_sources": slow_sources, "systems": sorted(systems.values(), key=lambda item: item["system_id"]), } diff --git a/scripts/intel/sources/runner.py b/scripts/intel/sources/runner.py index 88634c64..118066f6 100644 --- a/scripts/intel/sources/runner.py +++ b/scripts/intel/sources/runner.py @@ -4,6 +4,7 @@ import os import xml.etree.ElementTree as ET from concurrent.futures import ThreadPoolExecutor, as_completed from datetime import datetime +from time import perf_counter from typing import Any, Dict, List, Optional, Tuple import requests @@ -56,13 +57,19 @@ def failure_summary(failure: Dict[str, Any]) -> str: return failure.get("summary") or f"{failure.get('system_id')}::{failure.get('source_name')}::{failure.get('category')}::{failure.get('exception')}" -def build_failure(system: Dict[str, Any], source: Dict[str, Any], exc: Exception) -> Dict[str, Any]: +def build_failure( + system: Dict[str, Any], + source: Dict[str, Any], + exc: Exception, + *, + elapsed_seconds: float | None = None, +) -> Dict[str, Any]: response = getattr(exc, "response", None) status_code = getattr(response, "status_code", None) category = _failure_category(exc) message = str(exc).strip() or exc.__class__.__name__ summary = f"{system['system_id']}::{source['name']}::{category}::{message}" - return { + failure = { "system_id": system["system_id"], "display_name": system["display_name"], "source_name": source["name"], @@ -75,6 +82,9 @@ def build_failure(system: Dict[str, Any], source: Dict[str, Any], exc: Exception "url": source.get("url") or "", "summary": summary, } + if elapsed_seconds is not None: + failure["elapsed_seconds"] = round(elapsed_seconds, 3) + return failure def _collect_jobs( @@ -113,6 +123,7 @@ def _collect_source_candidates( since_dt: Optional[datetime], include_undated: bool, ) -> Tuple[List[Candidate], Optional[Dict[str, Any]]]: + started = perf_counter() handler = HANDLERS.get(source["kind"]) if handler is None: return ( @@ -136,7 +147,7 @@ def _collect_source_candidates( filtered = [item for item in items if _passes_since(item, since_dt, include_undated)] return filtered, None except Exception as exc: - return [], build_failure(system, source, exc) + return [], build_failure(system, source, exc, elapsed_seconds=perf_counter() - started) def probe_source(system: Dict[str, Any], source: Dict[str, Any]) -> Dict[str, Any]: @@ -279,9 +290,10 @@ def probe_sources( probes: List[Dict[str, Any]] = [] failures: List[Dict[str, Any]] = [] with ThreadPoolExecutor(max_workers=_max_workers(len(jobs))) as executor: - future_map = {executor.submit(probe_source, system, source): (system, source) for system, source in jobs} + future_map = {executor.submit(probe_source, system, source): (system, source, perf_counter()) for system, source in jobs} for future in as_completed(future_map): - system, source = future_map[future] + system, source, started = future_map[future] + elapsed = perf_counter() - started try: result = future.result() probes.append( @@ -289,11 +301,12 @@ def probe_sources( "system_id": system["system_id"], "source_name": source["name"], "source_kind": source["kind"], + "elapsed_seconds": round(elapsed, 3), **result, } ) except Exception as exc: - failures.append(build_failure(system, source, exc)) + failures.append(build_failure(system, source, exc, elapsed_seconds=elapsed)) probes.sort(key=lambda item: (item["system_id"], item["source_name"])) failures.sort(key=lambda item: (item.get("system_id", ""), item.get("source_name", ""), item.get("category", ""))) return probes, failures