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.

includes/wpinv-gateway-functions.php (5 issues)

1
<?php
2
/**
3
 * Contains gateway functions.
4
 *
5
 */
6
defined( 'ABSPATH' ) || exit;
7
8
/**
9
 * Returns an array of payment gateways.
10
 *
11
 * @return array
12
 */
13
function wpinv_get_payment_gateways() {
14
    return apply_filters( 'wpinv_payment_gateways', array() );
15
}
16
17
function wpinv_payment_gateway_titles( $all_gateways ) {
18
19
    $options  = wpinv_get_options();
20
    $gateways = array();
21
    foreach ( $all_gateways as $key => $gateway ) {
22
        if ( ! empty( $options[ $key . '_title' ] ) ) {
23
            $all_gateways[ $key ]['checkout_label'] = __( $options[ $key . '_title' ], 'invoicing' );
24
        }
25
26
        $gateways[ $key ] = isset( $options[ $key . '_ordering' ] ) ? $options[ $key . '_ordering' ] : ( isset( $gateway['ordering'] ) ? $gateway['ordering'] : '' );
27
    }
28
29
    asort( $gateways );
30
31
    foreach ( $gateways as $gateway => $key ) {
32
        $gateways[ $gateway ] = $all_gateways[ $gateway ];
33
    }
34
35
    return $gateways;
36
}
37
add_filter( 'wpinv_payment_gateways', 'wpinv_payment_gateway_titles', 1000, 1 );
38
39
/**
40
 * Returns an array of enabled gateways.
41
 *
42
 * @param bool $sort
43
 * @return array
44
 */
45
function wpinv_get_enabled_payment_gateways( $sort = false ) {
46
47
    $enabled = array();
48
49
    foreach ( wpinv_get_payment_gateways() as $gateway => $data ) {
50
51
        if ( (int) wpinv_get_option( "{$gateway}_active", $gateway === 'manual' ) === 1 ) {
52
            $enabled[ $gateway ] = $data;
53
        }
54
}
55
56
    if ( true === $sort ) {
57
        uasort( $enabled, 'wpinv_sort_gateway_order' );
58
59
        // Reorder our gateways so the default is first
60
        $default_gateway_id = wpinv_get_default_gateway();
61
        if ( isset( $enabled[ $default_gateway_id ] ) ) {
62
            $default_gateway = array(
63
                $default_gateway_id => $enabled[ $default_gateway_id ],
64
            );
65
66
            unset( $enabled[ $default_gateway_id ] );
67
            $enabled = array_merge( $default_gateway, $enabled );
68
        }
69
}
70
71
    return apply_filters( 'wpinv_enabled_payment_gateways', $enabled );
72
}
73
74
function wpinv_sort_gateway_order( $a, $b ) {
75
    return $a['ordering'] - $b['ordering'];
76
}
77
78
/**
79
 * Checks if a given gateway is active.
80
 *
81
 * @param string $gateway
82
 * @return bool
83
 */
84
function wpinv_is_gateway_active( $gateway ) {
85
    $is_active = (int) wpinv_get_option( "{$gateway}_active", $gateway === 'manual' ) === 1;
86
    return apply_filters( 'wpinv_is_gateway_active', $is_active, $gateway );
87
}
88
89
/**
90
 * Retrieves the default gateway.
91
 *
92
 * @return string|false
93
 */
94
function wpinv_get_default_gateway() {
95
    $default  = wpinv_get_option( 'default_gateway' );
96
    $gateways = wpinv_get_enabled_payment_gateways();
97
    $default  = ! empty( $default ) && isset( $gateways[ $default ] ) ? $default : false;
98
99
    return apply_filters( 'wpinv_default_gateway', $default );
100
}
101
102
/**
103
 * Returns a gateway's name.
104
 *
105
 * @param string $gateway The gateway to key.
106
 * @return string
107
 */
108
function wpinv_get_gateway_admin_label( $gateway ) {
109
110
    if ( empty( $gateway ) || 'none' == $gateway ) {
111
        return esc_html__( 'No Gateway', 'invoicing' );
112
    }
113
114
    $gateways = wpinv_get_payment_gateways();
115
    $label    = isset( $gateways[ $gateway ] ) ? $gateways[ $gateway ]['admin_label'] : $gateway;
116
    $gateway  = apply_filters( 'wpinv_gateway_admin_label', $label, $gateway );
117
118
    return wpinv_clean( $gateway );
0 ignored issues
show
Bug Best Practice introduced by
The expression return wpinv_clean($gateway) also could return the type array which is incompatible with the documented return type string.
Loading history...
119
}
120
121
/**
122
 * Retrieves the gateway description.
123
 *
124
 * @param string $gateway
125
 */
126
function wpinv_get_gateway_description( $gateway ) {
127
128
    $options     = wpinv_get_options();
129
    $description = ! empty( $options[ $gateway . '_desc' ] ) ? $options[ $gateway . '_desc' ] : '';
130
131
    return apply_filters( 'wpinv_gateway_description', $description, $gateway );
132
}
133
134
function wpinv_get_gateway_button_label( $gateway ) {
135
    return apply_filters( 'wpinv_gateway_' . $gateway . '_button_label', '' );
136
}
137
138
function wpinv_get_gateway_checkout_label( $gateway ) {
139
    $gateways = wpinv_get_payment_gateways();
140
    $label    = isset( $gateways[ $gateway ] ) ? $gateways[ $gateway ]['checkout_label'] : $gateway;
141
142
    if ( $gateway == 'none' ) {
143
        $label = __( 'None', 'invoicing' );
144
    }
145
146
    return apply_filters( 'wpinv_gateway_checkout_label', ucfirst( $label ), $gateway );
147
}
148
149
function wpinv_settings_sections_gateways( $settings ) {
150
    $gateways = wpinv_get_payment_gateways();
151
    ksort( $gateways );
152
153
    foreach ( $gateways as $key => $gateway ) {
154
        $settings[ $key ] = $gateway['admin_label'];
155
    }
156
157
    return $settings;
158
}
159
add_filter( 'wpinv_settings_sections_gateways', 'wpinv_settings_sections_gateways', 10, 1 );
160
161
/**
162
 * Adds GateWay settings.
163
 */
164
function wpinv_settings_gateways( $settings ) {
165
166
    // Loop through each gateway.
167
    foreach ( wpinv_get_payment_gateways() as $key => $gateway ) {
168
169
        $gateway_settings = array(
170
171
            // Header.
172
            "{$key}_header"   => array(
173
174
                'id'     => "{$key}_gateway_header",
175
                'name'   => '<h3>' . wp_sprintf( __( '%s Settings', 'invoicing' ), $gateway['admin_label'] ) . '</h3>',
176
                'custom' => $key,
177
                'type'   => 'gateway_header',
178
179
            ),
180
181
            // Activate/Deactivate a gateway.
182
            "{$key}_active"   => array(
183
                'id'   => $key . '_active',
184
                'name' => __( 'Activate', 'invoicing' ),
185
                'desc' => wp_sprintf( __( 'Enable %s', 'invoicing' ), $gateway['admin_label'] ),
186
                'type' => 'checkbox',
187
                'std'  => $key === 'manual' ? '1' : '0',
188
            ),
189
190
            // Activate/Deactivate sandbox.
191
            "{$key}_sandbox"  => array(
192
                'id'   => $key . '_sandbox',
193
                'name' => __( 'Sandbox', 'invoicing' ),
194
                'desc' => __( 'Enable sandbox to test payments', 'invoicing' ),
195
                'type' => 'checkbox',
196
                'std'  => '1',
197
            ),
198
199
            // Checkout title.
200
            "{$key}_title"    => array(
201
                'id'   => $key . '_title',
202
                'name' => __( 'Checkout Title', 'invoicing' ),
203
                'std'  => isset( $gateway['checkout_label'] ) ? $gateway['checkout_label'] : '',
204
                'type' => 'text',
205
            ),
206
207
            // Checkout description.
208
            "{$key}_desc"     => array(
209
                'id'   => $key . '_desc',
210
                'name' => __( 'Checkout Description', 'invoicing' ),
211
                'std'  => apply_filters( "getpaid_default_{$key}_checkout_description", '' ),
212
                'type' => 'text',
213
            ),
214
215
            // Checkout order.
216
            "{$key}_ordering" => array(
217
                'id'   => $key . '_ordering',
218
                'name' => __( 'Priority', 'invoicing' ),
219
                'std'  => apply_filters( "getpaid_default_{$key}_checkout_description", '' ),
220
                'type' => 'number',
221
                'step' => '1',
222
                'min'  => '0',
223
                'max'  => '100000',
224
                'std'  => isset( $gateway['ordering'] ) ? $gateway['ordering'] : '10',
225
            ),
226
227
        );
228
229
        // Maybe remove the sandbox.
230
        if ( ! getpaid_payment_gateway_supports( $key, 'sandbox' ) ) {
231
            unset( $gateway_settings[ "{$key}_sandbox" ] );
232
        }
233
234
        $gateway_settings = apply_filters( 'wpinv_gateway_settings', $gateway_settings, $key, $gateway );
235
        $gateway_settings = apply_filters( 'wpinv_gateway_settings_' . $key, $gateway_settings, $gateway );
236
237
        $settings[ $key ] = $gateway_settings;
238
    }
239
240
    do_action( 'getpaid_after_gateway_settings', $settings );
241
    return $settings;
242
243
}
244
add_filter( 'wpinv_settings_gateways', 'wpinv_settings_gateways', 10, 1 );
245
246
function wpinv_gateway_header_callback( $args ) {
247
    echo '<input type="hidden" id="wpinv_settings[save_gateway]" name="wpinv_settings[save_gateway]" value="' . esc_attr( $args['custom'] ) . '" />';
248
}
249
250
/**
251
 * Checks if a given gateway supports a given feature.
252
 *
253
 * @param string $gateway
254
 * @param string $feature
255
 * @return bool
256
 * @since 2.3.0
257
 */
258
function getpaid_payment_gateway_supports( $gateway, $feature ) {
259
260
    $supports = false;
0 ignored issues
show
The assignment to $supports is dead and can be removed.
Loading history...
261
262
    $supports = apply_filters( "getpaid_{$gateway}_supports_{$feature}", false );
263
264
    // Backwards compatibility.
265
    $supports = apply_filters( "wpinv_{$gateway}_supports_{$feature}", $supports );
266
    $supports = apply_filters( "wpinv_{$gateway}_support_{$feature}", $supports );
267
268
    $supports = apply_filters( "getpaid_gateway_supports_{$feature}", $supports, $gateway );
269
    $supports = apply_filters( 'getpaid_payment_gateway_supports', $supports, $feature, $gateway );
270
271
    return $supports;
272
}
273
274
function wpinv_get_chosen_gateway( $invoice_id = 0 ) {
275
	$gateways = array_keys( wpinv_get_enabled_payment_gateways() );
276
277
    $chosen = false;
278
    if ( $invoice_id > 0 && $invoice = wpinv_get_invoice( $invoice_id ) ) {
279
        $chosen = $invoice->get_gateway();
280
    }
281
282
	$chosen   = isset( $_REQUEST['payment-mode'] ) ? sanitize_text_field( $_REQUEST['payment-mode'] ) : $chosen;
283
284
	if ( false !== $chosen ) {
285
		$chosen = preg_replace( '/[^a-zA-Z0-9-_]+/', '', $chosen );
286
	}
287
288
	if ( ! empty( $chosen ) ) {
289
		$enabled_gateway = urldecode( $chosen );
290
	} elseif ( ! empty( $invoice ) && (float)$invoice->get_subtotal() <= 0 ) {
291
		$enabled_gateway = 'manual';
292
	} else {
293
		$enabled_gateway = wpinv_get_default_gateway();
294
	}
295
296
    if ( ! wpinv_is_gateway_active( $enabled_gateway ) && ! empty( $gateways ) ) {
0 ignored issues
show
It seems like $enabled_gateway can also be of type false; however, parameter $gateway of wpinv_is_gateway_active() 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

296
    if ( ! wpinv_is_gateway_active( /** @scrutinizer ignore-type */ $enabled_gateway ) && ! empty( $gateways ) ) {
Loading history...
297
        if ( wpinv_is_gateway_active( wpinv_get_default_gateway() ) ) {
298
            $enabled_gateway = wpinv_get_default_gateway();
299
        } else {
300
            $enabled_gateway = $gateways[0];
301
        }
302
}
303
304
	return apply_filters( 'wpinv_chosen_gateway', $enabled_gateway );
305
}
306
307
function wpinv_record_gateway_error( $title = '', $message = '' ) {
308
    return wpinv_error_log( $message, $title );
0 ignored issues
show
Are you sure the usage of wpinv_error_log($message, $title) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
309
}
310
311
function wpinv_count_sales_by_gateway( $gateway_id = 'paypal', $status = 'publish' ) {
312
	$ret  = 0;
313
	$args = array(
314
		'meta_key'    => '_wpinv_gateway',
315
		'meta_value'  => $gateway_id,
316
		'nopaging'    => true,
317
		'post_type'   => 'wpi_invoice',
318
		'post_status' => $status,
319
		'fields'      => 'ids',
320
	);
321
322
	$payments = new WP_Query( $args );
323
324
	if ( $payments ) {
0 ignored issues
show
$payments is of type WP_Query, thus it always evaluated to true.
Loading history...
325
		$ret = $payments->post_count;
326
    }
327
	return $ret;
328
}
329
330
/**
331
 * Displays the ipn url field.
332
 */
333
function wpinv_ipn_url_callback( $args ) {
334
    $sanitize_id = esc_attr( wpinv_sanitize_key( $args['id'] ) );
335
336
    echo '<input class="regular-text" type="text" ' . ( $args['readonly'] ? ' readonly' : '' ) . ' value="' . esc_attr( $args['std'] ) . '" name="wpinv_settings[' . esc_attr( $sanitize_id ) . ']" id="wpinv_settings[' . esc_attr( $sanitize_id ) . ']" onClick="this.select()">';
337
    echo '<label for="wpinv_settings[' . esc_attr( $sanitize_id ) . ']">' . wp_kses_post( $args['desc'] ) . '</label>';
338
339
}
340
341
/**
342
 * Checks if a gateway is in test mode.
343
 *
344
 * @param string $gateway The gateway to check for.
345
 *
346
 * @return bool
347
 */
348
function wpinv_is_test_mode( $gateway = '' ) {
349
    $sandbox  = empty( $gateway ) ? false : wpinv_get_option( "{$gateway}_sandbox", true );
350
    $supports = getpaid_payment_gateway_supports( $gateway, 'sandbox' );
351
    return apply_filters( 'wpinv_is_test_mode', $sandbox && $supports, $gateway );
352
}
353
354
/**
355
 * Retrieves the ipn url.
356
 *
357
 * @param string $gateway The gateway whose IPN url we should retrieve.
358
 * @param array $args extra args to add to the url.
359
 *
360
 * @return string
361
 */
362
function wpinv_get_ipn_url( $gateway = false, $args = array() ) {
363
    $args = wp_parse_args(
364
        array(
365
            'wpi-listener' => 'IPN',
366
            'wpi-gateway'  => $gateway,
367
        ),
368
        $args
369
    );
370
371
    return apply_filters( 'wpinv_ipn_url', add_query_arg( $args, home_url( 'index.php' ) ), $gateway, $args );
372
373
}
374
375
/**
376
 * Retrieves the non-query string ipn url.
377
 *
378
 * @param string $gateway The gateway whose IPN url we should retrieve.
379
 *
380
 * @return string
381
 */
382
function getpaid_get_non_query_string_ipn_url( $gateway ) {
383
    $gateway = wpinv_sanitize_key( $gateway );
384
    return home_url( "getpaid-ipn/$gateway" );
385
}
386
387
388
/**
389
 * Retrieves request data with slashes removed slashes.
390
 */
391
function wpinv_get_post_data( $method = 'request' ) {
392
393
    if ( $method == 'post' ) {
394
        return wp_kses_post_deep( wp_unslash( $_POST ) );
395
    }
396
397
    if ( $method == 'get' ) {
398
        return wp_kses_post_deep( wp_unslash( $_GET ) );
399
    }
400
401
    return wp_kses_post_deep( wp_unslash( $_REQUEST ) );
402
403
}
404
405
/**
406
 * Checks if a given gateway supports subscription payments.
407
 */
408
function wpinv_gateway_support_subscription( $gateway ) {
409
    return getpaid_payment_gateway_supports( $gateway, 'subscription' );
410
}
411
412
/**
413
 * Filters payment form gateways.
414
 *
415
 * @param array $gateways an array of gateways.
416
 * @param GetPaid_Payment_Form $form payment form.
417
 */
418
function wpinv_payment_gateways_on_cart( $gateways, $form ) {
419
420
    if ( $form->is_recurring() ) {
421
422
        foreach ( array_keys( $gateways ) as $gateway ) {
423
424
            if ( ! wpinv_gateway_support_subscription( $gateway ) ) {
425
                unset( $gateways[ $gateway ] );
426
            }
427
}
428
}
429
430
    return $gateways;
431
}
432
add_filter( 'getpaid_payment_form_gateways', 'wpinv_payment_gateways_on_cart', 10, 2 );
433