mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2024-11-26 11:26:31 +03:00
[CVEDetailsBridge] Add bridge (#2332)
CVE Details is a collection of CVEs, taken from the National Vulnerability Database (NVD) and other sources like the Exploit DB and Metasploit. The website categorizes it by vendor and product and attach the CWE category. There is an Atom feed available, but only logged in users can use it, it is not reliable and contain no useful information. This bridge create a sane feed with additional information like tags and a link to the CWE a description of the vulnerability.
This commit is contained in:
parent
814711e3af
commit
e1290aa42c
1 changed files with 141 additions and 0 deletions
141
bridges/CVEDetailsBridge.php
Normal file
141
bridges/CVEDetailsBridge.php
Normal file
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
// CVE Details is a collection of CVEs, taken from the National Vulnerability
|
||||
// Database (NVD) and other sources like the Exploit DB and Metasploit. The
|
||||
// website categorizes it by vendor and product and attach the CWE category.
|
||||
// There is a Atom feed available, but only logged in users can use it,
|
||||
// it is not reliable and contain no useful information. This bridge create a
|
||||
// sane feed with additional information like tags and a link to the CWE
|
||||
// a description of the vulnerability.
|
||||
class CVEDetailsBridge extends BridgeAbstract {
|
||||
const MAINTAINER = 'Aaron Fischer';
|
||||
const NAME = 'CVE Details';
|
||||
const CACHE_TIMEOUT = 60 * 60 * 6; // 6 hours
|
||||
const DESCRIPTION = 'Report new CVE vulnerabilities for a given vendor (and product)';
|
||||
const URI = 'https://www.cvedetails.com';
|
||||
|
||||
const PARAMETERS = array(array(
|
||||
// The Vendor ID can be taken from the URL
|
||||
'vendor_id' => array(
|
||||
'name' => 'Vendor ID',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'exampleValue' => 74, // PHP
|
||||
),
|
||||
// The optional Product ID can be taken from the URL as well
|
||||
'product_id' => array(
|
||||
'name' => 'Product ID',
|
||||
'type' => 'number',
|
||||
'required' => false,
|
||||
'exampleValue' => 128, // PHP
|
||||
),
|
||||
));
|
||||
|
||||
private $html = null;
|
||||
private $vendor = '';
|
||||
private $product = '';
|
||||
|
||||
// Return the URL to query.
|
||||
// Because of the optional product ID, we need to attach it if it is
|
||||
// set. The search result page has the exact same structure (with and
|
||||
// without the product ID).
|
||||
private function _buildURL() {
|
||||
$url = self::URI . '/vulnerability-list/vendor_id-' . $this->getInput('vendor_id');
|
||||
if ($this->getInput('product_id') !== '') {
|
||||
$url .= '/product_id-' . $this->getInput('product_id');
|
||||
}
|
||||
// Sadly, there is no way (prove me wrong please) to sort the search
|
||||
// result by publish date. So the nearest alternative is the CVE
|
||||
// number, which should be mostly accurate.
|
||||
$url .= '?order=1'; // Order by CVE number DESC
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Make the actual request to cvedetails.com and stores the response
|
||||
// (HTML) for later use and extract vendor and product from it.
|
||||
private function _fetchContent() {
|
||||
$html = getSimpleHTMLDOM($this->_buildURL())
|
||||
or returnServerError('Request failed: ' . $this->_buildURL());
|
||||
$this->html = defaultLinkTo($html, self::URI);
|
||||
|
||||
$vendor = $html->find('#contentdiv > h1 > a', 0);
|
||||
if ($vendor == null) {
|
||||
returnServerError('Invalid Vendor ID ' .
|
||||
$this->getInput('vendor_id') .
|
||||
' or Product ID ' .
|
||||
$this->getInput('product_id'));
|
||||
}
|
||||
$this->vendor = $vendor->innertext;
|
||||
|
||||
$product = $html->find('#contentdiv > h1 > a', 1);
|
||||
if ($product != null) {
|
||||
$this->product = $product->innertext;
|
||||
}
|
||||
}
|
||||
|
||||
// Build the name of the feed.
|
||||
public function getName() {
|
||||
if ($this->getInput('vendor_id') == '') {
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
if ($this->html == null) {
|
||||
$this->_fetchContent();
|
||||
}
|
||||
|
||||
$name = 'CVE Vulnerabilities for ' . $this->vendor;
|
||||
if ($this->product != '') {
|
||||
$name .= '/' . $this->product;
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
// Pull the data from the HTML response and fill the items..
|
||||
public function collectData() {
|
||||
if ($this->html == null) {
|
||||
$this->_fetchContent();
|
||||
}
|
||||
|
||||
foreach ($this->html->find('#vulnslisttable .srrowns') as $i => $tr) {
|
||||
// There are some optional vulnerability types, which will be
|
||||
// added to the categories as well as the CWE number -- which is
|
||||
// always given.
|
||||
$categories = array($this->vendor);
|
||||
$enclosures = array();
|
||||
|
||||
$cwe = $tr->find('td', 2)->find('a', 0);
|
||||
if ($cwe != null) {
|
||||
$cwe = $cwe->innertext;
|
||||
$categories[] = 'CWE-' . $cwe;
|
||||
$enclosures[] = 'https://cwe.mitre.org/data/definitions/' . $cwe . '.html';
|
||||
}
|
||||
$c = $tr->find('td', 4)->innertext;
|
||||
if (trim($c) != '') {
|
||||
$categories[] = $c;
|
||||
}
|
||||
if ($this->product != '') {
|
||||
$categories[] = $this->product;
|
||||
}
|
||||
|
||||
// The CVE number itself
|
||||
$title = $tr->find('td', 1)->find('a', 0)->innertext;
|
||||
|
||||
$this->items[] = array(
|
||||
'uri' => $tr->find('td', 1)->find('a', 0)->href,
|
||||
'title' => $title,
|
||||
'timestamp' => $tr->find('td', 5)->innertext,
|
||||
'content' => $tr->next_sibling()->innertext,
|
||||
'categories' => $categories,
|
||||
'enclosures' => $enclosures,
|
||||
'uid' => $tr->find('td', 1)->find('a', 0)->innertext,
|
||||
);
|
||||
|
||||
// We only want to fetch the latest 10 CVEs
|
||||
if (count($this->items) >= 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue