File: /var/www/clients/client6/web57/web/wffence/wp-cli-wordfence/src/VulnerabilityScanner.php
<?php
namespace GeneroWP\WpCliWordfence;
use Generator;
use GeneroWP\WpCliWordfence\Models\AffectedVersion;
use GeneroWP\WpCliWordfence\Models\Record;
use WP_CLI;
class VulnerabilityScanner
{
const TRANSIENT_LAST_SCAN_TIME = '_wpcliwf-last-scan-time';
/** @var string[] $software */
protected array $software = [];
public function __construct(
protected WordfenceApi $api
) {
}
/**
* @param string[] $slugs
*/
public function setSoftwareLimit(array $slugs): void
{
$this->software = $slugs;
}
/**
* @return Generator<Record,VulnerabilityException>
*/
public function next(): Generator
{
foreach ($this->api->getKnownVulnerabilities() as $record) {
if (! $this->isApplied($record)) {
continue;
}
try {
$this->validate($record);
} catch (VulnerabilityException $e) {
yield $record => $e;
}
}
}
protected function isApplied(Record $record): bool
{
if ($this->software) {
$isCorrectSoftware = array_reduce(
$this->software,
fn ($isMatch, $slug) => $isMatch || $record->isSoftware($slug),
false,
);
if (! $isCorrectSoftware) {
return false;
}
}
return true;
}
/**
* @throws VulnerabilityException
*/
protected function validate(Record $record): void
{
$plugins = $this->getPlugins();
// @todo themes
foreach ($record->software as $software) {
$activeVersion = match ($software->type) {
'core' => $this->getWpVersion(),
'plugin' => $plugins[$software->slug] ?? null,
default => null,
};
if (! $activeVersion) {
continue;
}
foreach ($software->affectedVersions as $affectedVersion) {
if (! $affectedVersion->isVersionAffected($activeVersion)) {
continue;
}
$message = sprintf(
'%s < %s < %s',
$affectedVersion->fromVersion,
$activeVersion,
$affectedVersion->toVersion,
);
throw new VulnerabilityException($message);
}
}
}
/**
* @return array<string,string> List of plugins with slug as key and version as value
*/
protected static function getPlugins(): array
{
static $plugins = [];
if (! $plugins) {
foreach (get_plugins() as $filename => $data) {
$slug = dirname($filename);
$plugins[$slug] = $data['Version'];
}
}
return $plugins;
}
protected static function getWpVersion(): string
{
return str_replace('-src', '', $GLOBALS['wp_version']);
}
}