Issues (51)

Security Analysis    not enabled

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
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
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
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.

include/Addon/License/BaseLicense.php (1 issue)

Labels
Severity
1
<?php namespace EmailLog\Addon\License;
2
3
use EmailLog\Addon\API\EDDAPI;
4
5
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
6
7
/**
8
 * Base class for for Bundle License and Add-on License.
9
 *
10
 * @since 2.0.0
11
 */
12
abstract class BaseLicense {
13
14
	protected $addon_name;
15
	protected $license_key;
16
	protected $license_data;
17
18
	/**
19
	 * EDD API Wrapper.
20
	 *
21
	 * @var \EmailLog\Addon\API\EDDAPI
22
	 */
23
	protected $edd_api;
24
25
	/**
26
	 * Get the option name in which license data will be stored.
27
	 *
28
	 * @return string Option name.
29
	 */
30
	abstract protected function get_option_name();
31
32
	/**
33
	 * Construct a new License object.
34
	 * If the API Wrapper is not provided, then a new one is initialized.
35
	 *
36
	 * @param \EmailLog\Addon\API\EDDAPI|null $edd_api (Optional) EDD API Wrapper instance. Default is null.
37
	 */
38
	public function __construct( $edd_api = null ) {
39
		if ( is_null( $edd_api ) ) {
40
			$edd_api = new EDDAPI();
41
		}
42
43
		$this->edd_api = $edd_api;
44
	}
45
46
	/**
47
	 * Set the license Key.
48
	 *
49
	 * @param string $license_key License Key.
50
	 */
51
	public function set_license_key( $license_key ) {
52
		$this->license_key = $license_key;
53
	}
54
55
	/**
56
	 * Get the license key.
57
	 *
58
	 * @return string|null License Key.
59
	 */
60
	public function get_license_key() {
61
		return $this->license_key;
62
	}
63
64
	/**
65
	 * Set add-on name.
66
	 *
67
	 * @param string $addon_name Add-on Name.
68
	 */
69
	public function set_addon_name( $addon_name ) {
70
		$this->addon_name = $addon_name;
71
	}
72
73
	/**
74
	 * Get the add-on name.
75
	 *
76
	 * @return string Add-on name.
77
	 */
78
	public function get_addon_name() {
79
		return $this->addon_name;
80
	}
81
82
	/**
83
	 * Get the expiry date of the license.
84
	 *
85
	 * @return false|string Expiry date in `yyyy-mm-dd hh:mm:ss` format if license is valid, False otherwise.
86
	 */
87
	public function get_expiry_date() {
88
		if ( ! empty( $this->license_data ) && isset( $this->license_data->expires ) ) {
89
			return $this->license_data->expires;
90
		}
91
92
		return false;
93
	}
94
95
	/**
96
	 * Has the bundle license expired?
97
	 *
98
	 * @since 2.3.0
99
	 *
100
	 * @return bool True if expired, False otherwise.
101
	 */
102
	public function has_expired() {
103
		$is_valid = $this->is_valid();
104
105
		if ( ! $is_valid ) {
106
			return true;
107
		}
108
109
		$expiry_date = $this->get_expiry_date();
110
111
		if ( ! $expiry_date ) {
112
			return true;
113
		}
114
115
		return ( strtotime( $expiry_date ) < time() );
116
	}
117
118
	/**
119
	 * Is the license activated and valid?
120
	 *
121
	 * @since 2.3.0 Moved to BaseLicense class.
122
	 *
123
	 * @return bool True if license is active, False otherwise.
124
	 */
125
	public function is_valid() {
126
		if ( ! $this->license_data instanceof \stdClass || ! isset( $this->license_data->license ) ) {
127
			return false;
128
		}
129
130
		return ( 'valid' === $this->license_data->license );
131
	}
132
133
	/**
134
	 * Get the renewal link for bundle license.
135
	 *
136
	 * @since 2.3.0
137
	 *
138
	 * @return string Renewal link.
139
	 */
140
	public function get_renewal_link() {
141
		$license_key = $this->get_license_key();
142
143
		if ( empty( $license_key ) ) {
144
			return 'https://wpemaillog.com/store/?utm_campaign=Renewal&utm_medium=wpadmin&utm_source=renewal-notice';
145
		}
146
147
		return sprintf( 'https://wpemaillog.com/checkout/?edd_license_key=%s&utm_campaign=Renewal&utm_medium=wpadmin&utm_source=renewal-notice', $license_key );
148
	}
149
150
	/**
151
	 * Activate License by calling EDD API.
152
	 * The license data returned by API is stored in an option.
153
	 *
154
	 * @throws \Exception In case of communication errors or License Issues.
155
	 *
156
	 * @return object API Response JSON Object.
157
	 */
158
	public function activate() {
159
		$response = $this->edd_api->activate_license( $this->get_license_key(), $this->get_addon_name() );
160
161
		if ( $response->success && 'valid' === $response->license ) {
162
			$response->license_key = $this->get_license_key();
163
164
			$this->store( $response );
165
166
			return $response;
167
		}
168
169
		switch ( $response->error ) {
170
			case 'expired':
171
				$message = sprintf(
172
					/* translators: 1 License expiry date, 2 License Renewal link */
173
					__( 'Your license key expired on %1$s. Please <a href="%2$s">renew it</a> to receive automatic updates and support.', 'email-log' ),
174
					date_i18n( get_option( 'date_format' ), strtotime( $response->expires, current_time( 'timestamp' ) ) ),
0 ignored issues
show
It seems like get_option('date_format') can also be of type false; however, parameter $format of date_i18n() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

174
					date_i18n( /** @scrutinizer ignore-type */ get_option( 'date_format' ), strtotime( $response->expires, current_time( 'timestamp' ) ) ),
Loading history...
175
					'https://wpemaillog.com/checkout/?edd_license_key=' . $this->get_license_key() . '&utm_campaign=Renewal&utm_medium=wpadmin&utm_source=activation-failed'
176
				);
177
				break;
178
179
			case 'revoked':
180
				$message = __( 'Your license key has been disabled.', 'email-log' );
181
				break;
182
183
			case 'missing':
184
				$message = __( 'Your license key is invalid.', 'email-log' );
185
				break;
186
187
			case 'invalid':
188
			case 'site_inactive':
189
				$message = __( 'Your license is not active for this URL.', 'email-log' );
190
				break;
191
192
			case 'item_name_mismatch':
193
				/* translators: 1 Add-on name */
194
				$message = sprintf( __( 'Your license key is not valid for %s.', 'email-log' ), $this->get_addon_name() );
195
				break;
196
197
			case 'no_activations_left':
198
				$message = sprintf(
199
					/* translators: 1 License Upgrade link */
200
					__( 'Your license key has reached its activation limit. Please <a href="%s">upgrade</a> your license.', 'email-log' ),
201
					'https://wpemaillog.com/account/?utm_campaign=Upgrade&utm_medium=wpadmin&utm_source=activation-failed'
202
				);
203
				break;
204
205
			default:
206
				$message = __( 'An error occurred, please try again.', 'email-log' );
207
				break;
208
		}
209
210
		throw new \Exception( $message );
211
	}
212
213
	/**
214
	 * Deactivate the license by calling EDD API.
215
	 * The stored license data will be cleared.
216
	 *
217
	 * @throws \Exception In case of communication errors.
218
	 *
219
	 * @return object API Response JSON object.
220
	 */
221
	public function deactivate() {
222
		$response = $this->edd_api->deactivate_license( $this->get_license_key(), $this->get_addon_name() );
223
224
		if ( $response->success && 'deactivated' === $response->license ) {
225
			$this->clear();
226
227
			return $response;
228
		}
229
230
		if ( $response->expires < time() ) {
231
			// license has expired. Expired license can't be de-activated. So let's just clear it.
232
			$this->clear();
233
234
			return $response;
235
		}
236
237
		$message = __( 'An error occurred, please try again.', 'email-log' );
238
239
		if ( isset( $response->error ) ) {
240
			$message .= ' ' . $response->error;
241
		}
242
243
		throw new \Exception( $message );
244
	}
245
246
	/**
247
	 * Get version information by calling EDD API.
248
	 * // TODO: Currently not used. Will be removed eventually.
249
	 *
250
	 * @throws \Exception In case of communication errors.
251
	 *
252
	 * @return object API Response JSON Object.
253
	 */
254
	public function get_version() {
255
		$response = $this->edd_api->get_version( $this->get_license_key(), $this->get_addon_name() );
256
257
		if ( isset( $response->new_version ) && ! isset( $response->msg ) ) {
258
			return $response;
259
		}
260
261
		$message = __( 'An error occurred, please try again', 'email-log' ) . $response->error;
262
263
		throw new \Exception( $message );
264
	}
265
266
	/**
267
	 * Load the license data from DB option.
268
	 */
269
	public function load() {
270
		$this->license_data = get_option( $this->get_option_name(), null );
271
	}
272
273
	/**
274
	 * Store License data in DB option.
275
	 *
276
	 * @access protected
277
	 *
278
	 * @param object $license_data License data.
279
	 */
280
	protected function store( $license_data ) {
281
		$this->license_data = $license_data;
282
		update_option( $this->get_option_name(), $license_data );
283
	}
284
285
	/**
286
	 * Clear stored license data.
287
	 *
288
	 * @access protected
289
	 */
290
	protected function clear() {
291
		$this->license_data = null;
292
		$this->license_key  = null;
293
		delete_option( $this->get_option_name() );
294
	}
295
}
296