Issues (197)

Security Analysis    not enabled

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

  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.
  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.
  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.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  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.
  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.
  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.
  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.
  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.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  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.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
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-wc-stripe-apple-pay-registration.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Stripe Apple Pay Registration Class.
4
 *
5
 * @since 4.0.6
6
 */
7
8
if ( ! defined( 'ABSPATH' ) ) {
9
	exit;
10
}
11
12
class WC_Stripe_Apple_Pay_Registration {
13
	/**
14
	 * Enabled.
15
	 *
16
	 * @var
17
	 */
18
	public $stripe_settings;
19
20
	/**
21
	 * Apple Pay Domain Set.
22
	 *
23
	 * @var bool
24
	 */
25
	public $apple_pay_domain_set;
26
27
	/**
28
	 * Stores Apple Pay domain verification issues.
29
	 *
30
	 * @var string
31
	 */
32
	public $apple_pay_verify_notice;
33
34
	public function __construct() {
35
		add_action( 'init', array( $this, 'add_domain_association_rewrite_rule' ) );
36
		add_filter( 'query_vars', array( $this, 'whitelist_domain_association_query_param' ), 10, 1 );
37
		add_action( 'parse_request', array( $this, 'parse_domain_association_request' ), 10, 1 );
38
39
		add_action( 'woocommerce_stripe_updated', array( $this, 'verify_domain_if_configured' ) );
40
		add_action( 'add_option_woocommerce_stripe_settings', array( $this, 'verify_domain_on_new_settings' ), 10, 2 );
41
		add_action( 'update_option_woocommerce_stripe_settings', array( $this, 'verify_domain_on_updated_settings' ), 10, 2 );
42
		add_action( 'admin_notices', array( $this, 'admin_notices' ) );
43
44
		$this->stripe_settings         = get_option( 'woocommerce_stripe_settings', array() );
45
		$this->apple_pay_domain_set    = 'yes' === $this->get_option( 'apple_pay_domain_set', 'no' );
46
		$this->apple_pay_verify_notice = '';
47
	}
48
49
	/**
50
	 * Gets the Stripe settings.
51
	 *
52
	 * @since 4.0.6
53
	 * @param string $setting
54
	 * @param string default
55
	 * @return string $setting_value
56
	 */
57
	public function get_option( $setting = '', $default = '' ) {
58
		if ( empty( $this->stripe_settings ) ) {
59
			return $default;
60
		}
61
62
		if ( ! empty( $this->stripe_settings[ $setting ] ) ) {
63
			return $this->stripe_settings[ $setting ];
64
		}
65
66
		return $default;
67
	}
68
69
	/**
70
	 * Whether the gateway and Payment Request Button (prerequisites for Apple Pay) are enabled.
71
	 *
72
	 * @since 4.5.4
73
	 * @return string Whether Apple Pay required settings are enabled.
74
	 */
75
	private function is_enabled() {
76
		$stripe_enabled                 = 'yes' === $this->get_option( 'enabled', 'no' );
77
		$payment_request_button_enabled = 'yes' === $this->get_option( 'payment_request', 'yes' );
78
79
		return $stripe_enabled && $payment_request_button_enabled;
80
	}
81
82
	/**
83
	 * Gets the Stripe secret key for the current mode.
84
	 *
85
	 * @since 4.5.3
86
	 * @return string Secret key.
87
	 */
88
	private function get_secret_key() {
89
		$testmode = 'yes' === $this->get_option( 'testmode', 'no' );
90
		return $testmode ? $this->get_option( 'test_secret_key' ) : $this->get_option( 'secret_key' );
91
	}
92
93
	/**
94
	 * Adds a rewrite rule for serving the domain association file from the proper location.
95
	 */
96
	public function add_domain_association_rewrite_rule() {
97
		$regex    = '^\.well-known\/apple-developer-merchantid-domain-association$';
98
		$redirect = 'index.php?apple-developer-merchantid-domain-association=1';
99
100
		add_rewrite_rule( $regex, $redirect, 'top' );
101
	}
102
103
	/**
104
	 * Add to the list of publicly allowed query variables.
105
	 *
106
	 * @param  array $query_vars - provided public query vars.
107
	 * @return array Updated public query vars.
108
	 */
109
	public function whitelist_domain_association_query_param( $query_vars ) {
110
		$query_vars[] = 'apple-developer-merchantid-domain-association';
111
		return $query_vars;
112
	}
113
114
	/**
115
	 * Serve domain association file when proper query param is provided.
116
	 *
117
	 * @param WP WordPress environment object.
118
	 */
119
	public function parse_domain_association_request( $wp ) {
120
		if (
121
			! isset( $wp->query_vars['apple-developer-merchantid-domain-association'] ) ||
122
			'1' !== $wp->query_vars['apple-developer-merchantid-domain-association']
123
		) {
124
			return;
125
		}
126
127
		$path = WC_STRIPE_PLUGIN_PATH . '/apple-developer-merchantid-domain-association';
128
		header( 'Content-Type: application/octet-stream' );
129
		echo esc_html( file_get_contents( $path ) );
130
		exit;
131
	}
132
133
	/**
134
	 * Makes request to register the domain with Stripe/Apple Pay.
135
	 *
136
	 * @since 3.1.0
137
	 * @version 4.5.4
138
	 * @param string $secret_key
139
	 */
140
	private function make_domain_registration_request( $secret_key ) {
141
		if ( empty( $secret_key ) ) {
142
			throw new Exception( __( 'Unable to verify domain - missing secret key.', 'woocommerce-gateway-stripe' ) );
143
		}
144
145
		$endpoint = 'https://api.stripe.com/v1/apple_pay/domains';
146
147
		$data = array(
148
			'domain_name' => $_SERVER['HTTP_HOST'],
149
		);
150
151
		$headers = array(
152
			'User-Agent'    => 'WooCommerce Stripe Apple Pay',
153
			'Authorization' => 'Bearer ' . $secret_key,
154
		);
155
156
		$response = wp_remote_post(
157
			$endpoint,
158
			array(
159
				'headers' => $headers,
160
				'body'    => http_build_query( $data ),
161
			)
162
		);
163
164
		if ( is_wp_error( $response ) ) {
165
			/* translators: error message */
166
			throw new Exception( sprintf( __( 'Unable to verify domain - %s', 'woocommerce-gateway-stripe' ), $response->get_error_message() ) );
167
		}
168
169
		if ( 200 !== $response['response']['code'] ) {
170
			$parsed_response = json_decode( $response['body'] );
171
172
			$this->apple_pay_verify_notice = $parsed_response->error->message;
173
174
			/* translators: error message */
175
			throw new Exception( sprintf( __( 'Unable to verify domain - %s', 'woocommerce-gateway-stripe' ), $parsed_response->error->message ) );
176
		}
177
	}
178
179
	/**
180
	 * Processes the Apple Pay domain verification.
181
	 *
182
	 * @since 3.1.0
183
	 * @version 4.5.4
184
	 *
185
	 * @param string $secret_key
186
	 *
187
	 * @return bool Whether domain verification succeeded.
188
	 */
189
	public function register_domain_with_apple( $secret_key ) {
190
		try {
191
			$this->make_domain_registration_request( $secret_key );
192
193
			// No errors to this point, verification success!
194
			$this->stripe_settings['apple_pay_domain_set'] = 'yes';
195
			$this->apple_pay_domain_set                    = true;
196
197
			update_option( 'woocommerce_stripe_settings', $this->stripe_settings );
198
199
			WC_Stripe_Logger::log( 'Your domain has been verified with Apple Pay!' );
200
201
			return true;
202
203
		} catch ( Exception $e ) {
204
			$this->stripe_settings['apple_pay_domain_set'] = 'no';
205
			$this->apple_pay_domain_set                    = false;
206
207
			update_option( 'woocommerce_stripe_settings', $this->stripe_settings );
208
209
			WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
210
211
			return false;
212
		}
213
	}
214
215
	/**
216
	 * Process the Apple Pay domain verification if proper settings are configured.
217
	 *
218
	 * @since 4.5.4
219
	 * @version 4.5.4
220
	 */
221
	public function verify_domain_if_configured() {
222
		$secret_key = $this->get_secret_key();
223
224
		if ( ! $this->is_enabled() || empty( $secret_key ) ) {
225
			return;
226
		}
227
228
		// Ensure that domain association file will be served.
229
		flush_rewrite_rules();
230
231
		// Register the domain with Apple Pay.
232
		$verification_complete = $this->register_domain_with_apple( $secret_key );
233
234
		// Show/hide notes if necessary.
235
		WC_Stripe_Inbox_Notes::notify_on_apple_pay_domain_verification( $verification_complete );
236
	}
237
238
	/**
239
	 * Conditionally process the Apple Pay domain verification after settings are initially set.
240
	 *
241
	 * @since 4.5.4
242
	 * @version 4.5.4
243
	 */
244
	public function verify_domain_on_new_settings( $option, $settings ) {
245
		$this->verify_domain_on_updated_settings( array(), $settings );
246
	}
247
248
	/**
249
	 * Conditionally process the Apple Pay domain verification after settings are updated.
250
	 *
251
	 * @since 4.5.3
252
	 * @version 4.5.4
253
	 */
254
	public function verify_domain_on_updated_settings( $prev_settings, $settings ) {
255
		// Grab previous state and then update cached settings.
256
		$this->stripe_settings = $prev_settings;
257
		$prev_secret_key       = $this->get_secret_key();
258
		$prev_is_enabled       = $this->is_enabled();
259
		$this->stripe_settings = $settings;
260
261
		// If Stripe or Payment Request Button wasn't enabled (or secret key was different) then might need to verify now.
262
		if ( ! $prev_is_enabled || ( $this->get_secret_key() !== $prev_secret_key ) ) {
263
			$this->verify_domain_if_configured();
264
		}
265
	}
266
267
	/**
268
	 * Display any admin notices to the user.
269
	 *
270
	 * @since 4.0.6
271
	 */
272
	public function admin_notices() {
273
		if ( ! $this->is_enabled() ) {
274
			return;
275
		}
276
277
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
278
			return;
279
		}
280
281
		$empty_notice = empty( $this->apple_pay_verify_notice );
282
		if ( $empty_notice && ( $this->apple_pay_domain_set || empty( $this->secret_key ) ) ) {
0 ignored issues
show
The property secret_key does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
283
			return;
284
		}
285
286
		/**
287
		 * Apple pay is enabled by default and domain verification initializes
288
		 * when setting screen is displayed. So if domain verification is not set,
289
		 * something went wrong so lets notify user.
290
		 */
291
		$allowed_html                      = array(
292
			'a' => array(
293
				'href'  => array(),
294
				'title' => array(),
295
			),
296
		);
297
		$verification_failed_without_error = __( 'Apple Pay domain verification failed.', 'woocommerce-gateway-stripe' );
298
		$verification_failed_with_error    = __( 'Apple Pay domain verification failed with the following error:', 'woocommerce-gateway-stripe' );
299
		$check_log_text                    = sprintf(
300
			/* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
301
			esc_html__( 'Please check the %1$slogs%2$s for more details on this issue. Logging must be enabled to see recorded logs.', 'woocommerce-gateway-stripe' ),
302
			'<a href="' . admin_url( 'admin.php?page=wc-status&tab=logs' ) . '">',
303
			'</a>'
304
		);
305
306
		?>
307
		<div class="error stripe-apple-pay-message">
308
			<?php if ( $empty_notice ) : ?>
309
				<p><?php echo esc_html( $verification_failed_without_error ); ?></p>
310
			<?php else : ?>
311
				<p><?php echo esc_html( $verification_failed_with_error ); ?></p>
312
				<p><i><?php echo wp_kses( make_clickable( esc_html( $this->apple_pay_verify_notice ) ), $allowed_html ); ?></i></p>
313
			<?php endif; ?>
314
			<p><?php echo $check_log_text; ?></p>
315
		</div>
316
		<?php
317
	}
318
}
319
320
new WC_Stripe_Apple_Pay_Registration();
321