# wpvulnerability/5.1.2/wpvulnerability-software.php

WPVulnerability, version 5.1.2. 278 lines.

- Page: https://pluginprobe.com/plugins/wpvulnerability/5.1.2/code/wpvulnerability-software.php
- Raw: https://pluginprobe.com/plugins/wpvulnerability/5.1.2/raw/wpvulnerability-software.php
- Modified: 2026-08-07T10:49:46+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/wpvulnerability/5.1.2/code/wpvulnerability-software.php#L10-L20`.

```php
<?php
/**
 * Software functions
 *
 * @package WPVulnerability
 *
 * @version 3.5.0
 */

defined( 'ABSPATH' ) || die( 'No script kiddies please!' );

/**
 * Retrieves the specified software version.
 *
 * This function returns the version of PHP, Apache, Nginx, MySQL, or MariaDB
 * after performing necessary validations. It ensures that the returned value
 * is clean and sanitized.
 *
 * @since 3.5.0
 * @since 4.3.0 Updated to handle hybrid detection format from ImageMagick, Redis, Memcached, and SQLite.
 *
 * @param string $software The name of the software ('php', 'apache', 'nginx', 'mysql', 'mariadb').
 * @return string|null The sanitized version of the software, or null if not found.
 */
function wpvulnerability_get_software_version( $software ) {
	switch ( $software ) {
		case 'php':
			$php_version = wpvulnerability_detect_php();
			if ( null !== $php_version && '' !== $php_version ) {
				return wp_kses( (string) $php_version, 'strip' );
			}

			break;

		case 'apache':
		case 'nginx':
			$webserver = wpvulnerability_detect_webserver();
			if ( isset( $webserver['id'] ) && $webserver['id'] === $software && ! empty( $webserver['version'] ) ) {
				return wp_kses( (string) $webserver['version'], 'strip' );
			}
			break;

		case 'mysql':
		case 'mariadb':
			$sqlserver = wpvulnerability_detect_sqlserver();
			if ( isset( $sqlserver['id'] ) && $sqlserver['id'] === $software && ! empty( $sqlserver['version'] ) ) {
				return wp_kses( (string) $sqlserver['version'], 'strip' );
			}
			break;

		case 'imagemagick':
			$detection = wpvulnerability_detect_imagemagick();
			if ( isset( $detection['version'] ) && 'unknown' !== $detection['version'] ) {
				return wp_kses( (string) $detection['version'], 'strip' );
			}

			break;

		case 'curl':
			$curl_version = wpvulnerability_detect_curl();
			if ( null !== $curl_version && '' !== $curl_version ) {
				return wp_kses( (string) $curl_version, 'strip' );
			}

			break;

		case 'memcached':
			$detection = wpvulnerability_detect_memcached();
			if ( isset( $detection['version'] ) && 'unknown' !== $detection['version'] ) {
				return wp_kses( (string) $detection['version'], 'strip' );
			}

			break;

		case 'redis':
			$detection = wpvulnerability_detect_redis();
			if ( isset( $detection['version'] ) && 'unknown' !== $detection['version'] ) {
				return wp_kses( (string) $detection['version'], 'strip' );
			}

			break;

		case 'sqlite':
			$detection = wpvulnerability_detect_sqlite();
			if ( isset( $detection['version'] ) && 'unknown' !== $detection['version'] ) {
				return wp_kses( (string) $detection['version'], 'strip' );
			}

			break;

		default:
			break;
	}

	return null;
}

/**
 * Retrieves vulnerabilities for a given software version and updates its data.
 *
 * This function detects the installed software version, checks for vulnerabilities using an external API,
 * and updates the data array with the vulnerabilities found.
 *
 * @since 3.5.0
 *
 * @param string $software The software name (e.g., 'php', 'apache', 'nginx', 'mysql', 'mariadb').
 *
 * @return array<string, mixed> The updated data array containing vulnerability information.
 */
function wpvulnerability_get_fresh_vulnerabilities( $software ) {

	$version = null;
	$data    = array(
		'vulnerabilities' => null,
		'vulnerable'      => 0,
		'lifecycle'       => array(),
	);

	switch ( $software ) {
		case 'php':
		case 'apache':
		case 'nginx':
		case 'mysql':
		case 'mariadb':
		case 'imagemagick':
		case 'curl':
		case 'memcached':
		case 'redis':
		case 'sqlite':
			$version = wpvulnerability_get_software_version( $software );
			break;

		default:
			return $data;
	}

	if ( $version ) {
		$transient_key = 'wpvulnerability_' . $software;

		// Delete the transient so the next call fetches fresh data and repopulates it.
		if ( is_multisite() ) {
			delete_site_transient( $transient_key );
		} else {
			delete_transient( $transient_key );
		}

		switch ( $software ) {
			case 'php':
			case 'apache':
			case 'nginx':
			case 'mysql':
			case 'mariadb':
			case 'imagemagick':
			case 'curl':
			case 'memcached':
			case 'redis':
			case 'sqlite':
				// cache=1: transient was just cleared, so a fresh API call is made and result cached.
				$api_response = wpvulnerability_get_vulnerabilities( $software, $version, 1 );
				break;
		}

		if ( ! empty( $api_response ) ) {
			$data['vulnerabilities'] = $api_response;
			$data['vulnerable']      = 1;
		}

		// Read back the transient to extract lifecycle fields from the full API response.
		$raw_body     = is_multisite() ? get_site_transient( $transient_key ) : get_transient( $transient_key );
		$raw_response = json_decode( is_string( $raw_body ) ? $raw_body : '', true );
		if ( is_array( $raw_response ) && isset( $raw_response['data'] ) && is_array( $raw_response['data'] ) ) {
			$resp_data         = $raw_response['data'];
			$data['lifecycle'] = array(
				'name'       => is_scalar( $resp_data['name'] ?? '' ) ? (string) ( $resp_data['name'] ?? '' ) : '',
				'status'     => is_scalar( $resp_data['status'] ?? '' ) ? (string) ( $resp_data['status'] ?? '' ) : '',
				'date_start' => is_scalar( $resp_data['date_start'] ?? '' ) ? (string) ( $resp_data['date_start'] ?? '' ) : '',
				'date_end'   => is_scalar( $resp_data['date_end'] ?? '' ) ? (string) ( $resp_data['date_end'] ?? '' ) : '',
			);
		}
	}

	return $data;
}


/**
 * Get Installed Software
 *
 * Retrieves the list of installed software versions, checks for vulnerabilities,
 * caches the data, and sends an email notification if vulnerabilities are detected.
 *
 * @since 3.5.0
 *
 * @param string $software The software name (e.g., 'php', 'apache').
 *
 * @return string JSON-encoded array of software data with vulnerabilities and vulnerable status.
 */
function wpvulnerability_get_installed( $software ) {

	$wpvulnerability_software_vulnerable = 0;

	// Retrieve fresh vulnerabilities for the installed software version.
	$data = wpvulnerability_get_fresh_vulnerabilities( $software );

	// Check if the software version is vulnerable and count the vulnerabilities.
	if ( isset( $data['vulnerable'] ) && is_numeric( $data['vulnerable'] ) && (int) $data['vulnerable'] ) {
		$vulns                               = isset( $data['vulnerabilities'] ) && is_array( $data['vulnerabilities'] ) ? $data['vulnerabilities'] : array();
		$wpvulnerability_software_vulnerable = count( $vulns );
	}

	// Cache the vulnerability data and the timestamp for cache expiration.
	if ( is_multisite() ) {
				update_site_option( 'wpvulnerability-' . $software, wp_json_encode( $data ) );
				update_site_option( 'wpvulnerability-' . $software . '-vulnerable', wp_json_encode( number_format( $wpvulnerability_software_vulnerable, 0, '.', '' ) ) );
				update_site_option( 'wpvulnerability-' . $software . '-cache', wp_json_encode( number_format( time() + ( 3600 * wpvulnerability_cache_hours() ), 0, '.', '' ) ) );
	} else {
				update_option( 'wpvulnerability-' . $software, wp_json_encode( $data ), false );
				update_option( 'wpvulnerability-' . $software . '-vulnerable', wp_json_encode( number_format( $wpvulnerability_software_vulnerable, 0, '.', '' ) ), false );
				update_option( 'wpvulnerability-' . $software . '-cache', wp_json_encode( number_format( time() + ( 3600 * wpvulnerability_cache_hours() ), 0, '.', '' ) ), false );
	}

	// Return the JSON-encoded array of software data.
	$encoded = wp_json_encode( $data );
	return false !== $encoded ? $encoded : '';
}

/**
 * Get cached software vulnerabilities without triggering remote calls.
 *
 * @since 3.5.0
 *
 * @param string $software The software name (e.g., 'php', 'apache').
 *
 * @return array<string, mixed>|null Array of software data with vulnerabilities, or null if software is invalid.
 */
function wpvulnerability_software_get_vulnerabilities( $software ) {

	$valid_software = array( 'php', 'apache', 'mariadb', 'mysql', 'nginx', 'imagemagick', 'curl', 'memcached', 'redis', 'sqlite' );

	// Use strict comparison for in_array.
	if ( in_array( $software, $valid_software, true ) ) {
		if ( is_multisite() ) {
			$raw  = get_site_option( 'wpvulnerability-' . $software );
			$data = json_decode( is_string( $raw ) ? $raw : '', true );
		} else {
			$raw  = get_option( 'wpvulnerability-' . $software );
			$data = json_decode( is_string( $raw ) ? $raw : '', true );
		}

		return is_array( $data ) ? $data : array();
	} else {
		return null;
	}
}

/**
 * Update the software cache and remove any old cache data.
 *
 * @since 3.0.0
 *
 * @param string $software The software name (e.g., 'php', 'apache').
 *
 * @return void
 */
function wpvulnerability_get_vulnerabilities_clean( $software ) {

	// Skip detection for components the administrator has hidden (either via the
	// analysis settings or a WPVULNERABILITY_HIDE_* wp-config constant). This
	// prevents shell_exec from running for components that are meant to be
	// deactivated, matching the behaviour of the core/plugins/themes clean functions.
	if ( ! wpvulnerability_analyze_filter( $software ) ) {
		return;
	}

	// Update the installed software cache.
	wpvulnerability_get_installed( $software );
}

```
