HEX
Server: Apache
System: Linux localhost.localdomain 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023 x86_64
User: web57 (5040)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
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']);
    }
}