Issues (850)

Security Analysis    4 potential vulnerabilities

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection (1)
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection (2)
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting (1)
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class-getpaid-maxmind-database-service.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
 * The MaxMind database service class file.
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
9
/**
10
 * The service class responsible for interacting with MaxMind databases.
11
 *
12
 * @since 1.0.19
13
 */
14
class GetPaid_MaxMind_Database_Service {
15
16
	/**
17
	 * The name of the MaxMind database to utilize.
18
	 */
19
	const DATABASE = 'GeoLite2-Country';
20
21
	/**
22
	 * The extension for the MaxMind database.
23
	 */
24
	const DATABASE_EXTENSION = '.mmdb';
25
26
	/**
27
	 * A prefix for the MaxMind database filename.
28
	 *
29
	 * @var string
30
	 */
31
	private $database_prefix;
32
33
	/**
34
	 * Class constructor.
35
	 *
36
	 * @param string|null $database_prefix A prefix for the MaxMind database filename.
37
	 */
38
	public function __construct( $database_prefix ) {
39
		$this->database_prefix = $database_prefix;
40
	}
41
42
	/**
43
	 * Fetches the path that the database should be stored.
44
	 *
45
	 * @return string The local database path.
46
	 */
47
	public function get_database_path() {
48
		$uploads_dir = wp_upload_dir();
49
50
		$database_path = trailingslashit( $uploads_dir['basedir'] ) . 'invoicing/';
51
		if ( ! empty( $this->database_prefix ) ) {
52
			$database_path .= $this->database_prefix . '-';
53
		}
54
		$database_path .= self::DATABASE . self::DATABASE_EXTENSION;
55
56
		// Filter the geolocation database storage path.
57
		return apply_filters( 'getpaid_maxmind_geolocation_database_path', $database_path );
58
	}
59
60
	/**
61
	 * Fetches the database from the MaxMind service.
62
	 *
63
	 * @param string $license_key The license key to be used when downloading the database.
64
	 * @return string|WP_Error The path to the database file or an error if invalid.
65
	 */
66
	public function download_database( $license_key ) {
67
68
		$download_uri = add_query_arg(
69
			array(
70
				'edition_id'  => self::DATABASE,
71
				'license_key' => urlencode( wpinv_clean( $license_key ) ),
72
				'suffix'      => 'tar.gz',
73
			),
74
			'https://download.maxmind.com/app/geoip_download'
75
		);
76
77
		// Needed for the download_url call right below.
78
		require_once ABSPATH . 'wp-admin/includes/file.php';
79
80
		$tmp_archive_path = download_url( esc_url_raw( $download_uri ) );
81
82
		if ( is_wp_error( $tmp_archive_path ) ) {
83
			// Transform the error into something more informative.
84
			$error_data = $tmp_archive_path->get_error_data();
85
			if ( isset( $error_data['code'] ) && $error_data['code'] == 401 ) {
86
				return new WP_Error(
87
					'getpaid_maxmind_geolocation_database_license_key',
88
					__( 'The MaxMind license key is invalid. If you have recently created this key, you may need to wait for it to become active.', 'invoicing' )
89
				);
90
			}
91
92
			return new WP_Error( 'getpaid_maxmind_geolocation_database_download', __( 'Failed to download the MaxMind database.', 'invoicing' ) );
93
		}
94
95
		// Extract the database from the archive.
96
		return $this->extract_downloaded_database( $tmp_archive_path );
0 ignored issues
show
$tmp_archive_path of type WP_Error is incompatible with the type string expected by parameter $tmp_archive_path of GetPaid_MaxMind_Database...t_downloaded_database(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

96
		return $this->extract_downloaded_database( /** @scrutinizer ignore-type */ $tmp_archive_path );
Loading history...
97
98
	}
99
100
	/**
101
	 * Extracts the downloaded database.
102
	 *
103
	 * @param string $tmp_archive_path The database archive path.
104
	 * @return string|WP_Error The path to the database file or an error if invalid.
105
	 */
106
	protected function extract_downloaded_database( $tmp_archive_path ) {
107
108
		// Extract the database from the archive.
109
		$tmp_database_path = '';
110
111
		try {
112
113
			$file              = new PharData( $tmp_archive_path );
114
			$tmp_database_path = trailingslashit( dirname( $tmp_archive_path ) ) . trailingslashit( $file->current()->getFilename() ) . self::DATABASE . self::DATABASE_EXTENSION;
115
116
			$file->extractTo(
117
				dirname( $tmp_archive_path ),
118
				trailingslashit( $file->current()->getFilename() ) . self::DATABASE . self::DATABASE_EXTENSION,
119
				true
120
			);
121
122
		} catch ( Exception $exception ) {
123
			return new WP_Error( 'invoicing_maxmind_geolocation_database_archive', $exception->getMessage() );
124
		} finally {
125
			// Remove the archive since we only care about a single file in it.
126
			unlink( $tmp_archive_path );
127
		}
128
129
		return $tmp_database_path;
130
	}
131
132
	/**
133
	 * Fetches the ISO country code associated with an IP address.
134
	 *
135
	 * @param string $ip_address The IP address to find the country code for.
136
	 * @return string The country code for the IP address, or empty if not found.
137
	 */
138
	public function get_iso_country_code_for_ip( $ip_address ) {
139
		$country_code = '';
140
141
		if ( ! class_exists( 'MaxMind\Db\Reader' ) ) {
142
			return $country_code;
143
		}
144
145
		$database_path = $this->get_database_path();
146
		if ( ! file_exists( $database_path ) ) {
147
			return $country_code;
148
		}
149
150
		try {
151
			$reader = new MaxMind\Db\Reader( $database_path );
152
			$data   = $reader->get( $ip_address );
153
154
			if ( isset( $data['country']['iso_code'] ) ) {
155
				$country_code = $data['country']['iso_code'];
156
			}
157
158
			$reader->close();
159
		} catch ( Exception $e ) {
160
			wpinv_error_log( $e->getMessage(), 'SOURCE: MaxMind GeoLocation' );
161
		}
162
163
		return $country_code;
164
	}
165
166
}
167