-
Notifications
You must be signed in to change notification settings - Fork 1k
/
CVEDetailsBridge.php
117 lines (103 loc) · 4.09 KB
/
CVEDetailsBridge.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?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 = [[
// The Vendor ID can be taken from the URL
'vendor_id' => [
'name' => 'Vendor ID',
'type' => 'number',
'required' => true,
'exampleValue' => 74, // PHP
],
// The optional Product ID can be taken from the URL as well
'product_id' => [
'name' => 'Product ID',
'type' => 'number',
'required' => false,
'exampleValue' => 128, // PHP
],
]];
private $html = null;
private $vendor = '';
private $product = '';
public function collectData()
{
if ($this->html == null) {
$this->fetchContent();
}
$var = $this->html->find('#searchresults > div > div.row');
foreach ($var as $i => $tr) {
$uri = $tr->find('h3 > a', 0)->href ?? null;
$title = $tr->find('h3 > a', 0)->innertext;
$content = $tr->find('.cvesummarylong', 0)->innertext ?? '';
$timestamp = $tr->find('[data-tsvfield="publishDate"]', 0)->innertext ?? 0;
$this->items[] = [
'uri' => $uri,
'title' => $title,
'timestamp' => $timestamp,
'content' => $content,
'categories' => [$this->vendor],
'enclosures' => [],
'uid' => $title,
];
if (count($this->items) >= 30) {
break;
}
}
}
// 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()
{
// build url
// 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).
$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
$html = getSimpleHTMLDOM($url);
$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;
}
}
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;
}
}