[ 'instance' => [ 'name' => 'OpenCVE Instance', 'required' => true, 'defaultValue' => 'https://www.opencve.io', 'exampleValue' => 'https://www.opencve.io' ], 'login' => [ 'name' => 'Login', 'type' => 'text', 'required' => true ], 'password' => [ 'name' => 'Password', 'type' => 'text', 'required' => true ], 'pages' => [ 'name' => 'Number of pages', 'type' => 'number', 'required' => false, 'exampleValue' => 1, 'defaultValue' => 1 ], 'filter' => [ 'name' => 'Filter', 'type' => 'text', 'required' => false, 'exampleValue' => 'search:jenkins;product:gitlab,cvss:critical', 'title' => 'Syntax: param1:value1,param2:value2;param1query2:param2query2. See https://docs.opencve.io/api/cve/ for parameters' ], 'upd_timestamp' => [ 'name' => 'Use updated_at instead of created_at as timestamp', 'type' => 'checkbox' ], 'trunc_summary' => [ 'name' => 'Truncate summary for header', 'type' => 'number', 'defaultValue' => 100 ], 'fetch_contents' => [ 'name' => 'Fetch detailed contents for CVEs', 'defaultValue' => 'checked', 'type' => 'checkbox' ] ] ]; const CSS = ' '; public function collectData() { $creds = $this->getInput('login') . ':' . $this->getInput('password'); $authHeader = 'Authorization: Basic ' . base64_encode($creds); $instance = $this->getInput('instance'); $queries = []; $filter = $this->getInput('filter'); $filterValues = []; if ($filter && mb_strlen($filter) > 0) { $filterValues = explode(';', $filter); } else { $queries[''] = []; } foreach ($filterValues as $filterValue) { $params = explode(',', $filterValue); $queryName = $filterValue; $query = []; foreach ($params as $param) { [$key, $value] = explode(':', $param); if ($key == 'title') { $queryName = $value; } else { $query[$key] = $value; } } $queries[$queryName] = $query; } $fetchedIds = []; foreach ($queries as $queryName => $query) { for ($i = 1; $i <= $this->getInput('pages'); $i++) { $queryPaginated = array_merge($query, ['page' => $i]); $url = $instance . '/api/cve?' . http_build_query($queryPaginated); $response = getContents($url, [$authHeader]); $titlePrefix = ''; if (count($queries) > 1) { $titlePrefix = '[' . $queryName . '] '; } foreach (json_decode($response) as $cveItem) { if (array_key_exists($cveItem->id, $fetchedIds)) { continue; } $fetchedIds[$cveItem->id] = true; $item = [ 'uri' => $instance . '/cve/' . $cveItem->id, 'uid' => $cveItem->id, ]; if ($this->getInput('upd_timestamp') == 1) { $item['timestamp'] = strtotime($cveItem->updated_at); } else { $item['timestamp'] = strtotime($cveItem->created_at); } if ($this->getInput('fetch_contents')) { [$content, $title] = $this->fetchContents( $cveItem, $titlePrefix, $instance, $authHeader ); $item['content'] = $content; $item['title'] = $title; } else { $item['content'] = $cveItem->summary . $this->getLinks($cveItem->id); $item['title'] = $this->getTitle($titlePrefix, $cveItem); } $this->items[] = $item; } } } usort($this->items, function ($a, $b) { return $b['timestamp'] - $a['timestamp']; }); } private function getTitle($titlePrefix, $cveItem) { $summary = $cveItem->summary; $limit = $this->getInput('limit'); if ($limit && mb_strlen($summary) > 100) { $summary = mb_substr($summary, 0, $limit) + '...'; } return $titlePrefix . $cveItem->id . '. ' . $summary; } private function fetchContents($cveItem, $titlePrefix, $instance, $authHeader) { $url = $instance . '/api/cve/' . $cveItem->id; $response = getContents($url, [$authHeader]); $datum = json_decode($response); $title = $this->getTitleFromDatum($datum, $titlePrefix); $result = self::CSS; $result .= '
' . $datum->summary . '
'; $result .= <<
EOD; } private function getV3Table($datum) { $metrics = $datum->raw_nvd_data->metrics; if (!isset($metrics->cvssMetricV31) || count($metrics->cvssMetricV31) == 0) { return ''; } $v3 = $metrics->cvssMetricV31[0]; $data = $v3->cvssData; return <<
Impact score | {$v3->impactScore} | Exploitability score | {$v3->exploitabilityScore} |
Attack vector | {$data->attackVector} | Confidentiality Impact | {$data->confidentialityImpact} |
Attack complexity | {$data->attackComplexity} | Integrity Impact | {$data->integrityImpact} |
Privileges Required | {$data->privilegesRequired} | Availability Impact | {$data->availabilityImpact} |
User Interaction | {$data->userInteraction} | Scope | {$data->scope} |
Impact score | {$v2->impactScore} | Exploitability score | {$v2->exploitabilityScore} |
Access Vector | {$data->accessVector} | Confidentiality Impact | {$data->confidentialityImpact} |
Access Complexity | {$data->accessComplexity} | Integrity Impact | {$data->integrityImpact} |
Authentication | {$data->authentication} | Availability Impact | {$data->availabilityImpact} |