PluginProbe
Injection Guard / trunk
Injection Guard vtrunk
trunk 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1
injection-guard / functions.php

functions.php in Injection Guard trunk, at functions.php

465 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php require_once('guard.php');
2
3
4
5
6
7
8
9 //FOR QUICK DEBUGGING
10
11
12
13 if(!function_exists('pre')){
14
15 function pre($data){
16
17 if(isset($_GET['debug'])){
18
19 pree($data);
20
21 }
22
23 }
24
25 }
26
27 if(!function_exists('pree')){
28
29 function pree($data){
30
31 echo '<pre>';
32
33 print_r($data);
34
35 echo '</pre>';
36
37
38
39 }
40
41 }
42
43
44
45
46
47
48
49 if(!function_exists('ig_start')){
50
51
52
53
54
55 function ig_start(){
56
57
58
59 $guard_obj = new guard_wordpress;
60
61 $guard_obj->init();
62
63 $guard_obj->update_log();
64
65 $ig_logs = $guard_obj->get_requests_log();
66
67 $ig_blacklisted = $guard_obj->get_blacklisted();
68
69 $uri = $guard_obj->wp_uri_cleaned();
70
71 $aus = $guard_obj->available_uri_strings();
72
73
74
75
76
77 if(isset($ig_blacklisted[$uri]))
78
79 {
80
81 $diff = array_intersect($ig_blacklisted[$uri], $aus);
82
83
84
85 if(!empty($diff)){
86
87 global $wp_query;
88
89 $wp_query->set_404();
90
91 status_header( 404 );
92
93 get_template_part( 404 );
94
95 exit();
96
97 }
98
99 }
100
101
102
103 }
104
105
106
107
108
109 }
110
111
112
113
114
115 if(!function_exists('ig_update')){
116
117 function ig_update(){
118
119
120
121 $ret = array('status'=>true);
122
123 if (
124 ! isset( $_POST['ig_nonce'] )
125 || ! wp_verify_nonce( $_POST['ig_nonce'], 'ig_nonce_action' )
126 ) {
127
128 print __('Sorry, your nonce did not verify.','injection-guard');
129 exit;
130
131 } elseif(is_super_admin()) {
132
133 $val = isset($_POST['val']) ? sanitize_text_field($_POST['val']) : '';
134
135
136 $type = isset($_POST['type']) && in_array($_POST['type'], ['whitelist','blacklist']) ? $_POST['type'] : 'blacklist';
137
138
139 $uri = isset($_POST['uri_index'])?esc_attr($_POST['uri_index']):'';
140
141
142
143
144 $guard_obj = new guard_wordpress;
145
146
147
148 if($type=='whitelist'){
149
150 $guard_obj->update_blacklisted($val, $uri, false);
151
152 }else{
153
154 $guard_obj->update_blacklisted($val, $uri, true);
155
156 }
157
158
159 wp_send_json_success($ret);
160
161
162 }
163
164
165 }
166
167 }
168
169
170
171 function ig_plugin_links($links) {
172
173 global $ig_pro, $ig_pro_link;
174
175 $settings_link = '<a href="options-general.php?page=ig_settings">'.__('Settings', 'injection-guard').'</a>';
176
177 $premium_link = '';
178
179 if(!$ig_pro){
180 $premium_link = '<a href="'.$ig_pro_link.'" title="'.__('Go Premium', 'injection-guard').'" target="_blank">'.__('Go Premium', 'injection-guard').'</a>';
181 }
182
183 array_unshift($links, $settings_link,$premium_link);
184
185 return $links;
186
187 }
188
189 function ig_get_ip()
190 {
191 $ip = '';
192 $sources = array (
193 'REMOTE_ADDR',
194 'HTTP_X_FORWARDED_FOR',
195 'HTTP_CLIENT_IP',
196 );
197
198 foreach ( $sources as $source ) {
199 if ( isset ( $_SERVER[ $source ] ) ) {
200 $ip = $_SERVER[ $source ];
201 } elseif ( getenv( $source ) ) {
202 $ip = getenv( $source );
203 }
204 }
205
206 return $ip;
207 }
208
209 function ig_user_last_login( $user_login, $user ) {
210 update_user_meta( $user->ID, 'last_login', time() );
211 $ips = get_user_meta( $user->ID, 'ip_logs', true);
212 $ips = is_array($ips)?$ips:array();
213 $ips[] = ig_get_ip();
214 $ips = array_unique($ips);
215 update_user_meta( $user->ID, 'ip_logs', $ips);
216
217 }
218 add_action( 'wp_login', 'ig_user_last_login', 10, 2 );
219
220 function ig_get_customer_total_order($user_id=0) {
221 global $wpdb;
222 $customer_orders = get_posts( array(
223 'numberposts' => - 1,
224 'meta_key' => '_customer_user',
225 'meta_value' => $user_id?$user_id:get_current_user_id(),
226 'post_type' => array( 'shop_order' ),
227 'post_status' => array( 'wc-completed' )
228 ) );
229 //pree($customer_orders);
230 $total = 0;
231 $products = array();
232 if(!empty($customer_orders)){
233 foreach ( $customer_orders as $customer_order ) {
234 //pree($customer_order->ID);
235 $order = wc_get_order( $customer_order );
236 //pree($order);
237 //pree($order->get_items());
238 if(!empty($order) && count($order->get_items())>0){
239 foreach ($order->get_items() as $item_id => $item_data) {
240 $product = $item_data->get_product();
241 if(!empty($product)){
242
243 $product_name = $product->get_name();
244 $item_quantity = $item_data->get_quantity();
245 $permissions_query = $wpdb->prepare( "
246 SELECT * FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
247 WHERE order_id = %d ORDER BY product_id
248 ", $order->id );
249 //pree($permissions_query);
250 $download_permissions = $wpdb->get_results($permissions_query);
251 //pree($download_permissions);
252 $download_count = 0;
253 if(!empty($download_permissions)){
254 $for_download_count = current($download_permissions);
255 $download_count = $for_download_count->download_count;
256 }
257
258 $products[] = array('qty'=>$item_quantity, 'product'=>$product_name, 'download_count'=>$download_count);
259 }
260 }
261 }
262 //pree($order);
263 $total += $order->get_total();
264 }
265 }
266
267 return array(count($customer_orders), $total, $products);
268 }
269
270 if (!function_exists('ig_update_bulk_backlist')) {
271 function ig_update_bulk_backlist() {
272 // Verify nonce first
273 if (!isset($_POST['ig_nonce']) || !wp_verify_nonce($_POST['ig_nonce'], 'ig_nonce_action')) {
274 wp_send_json_error(['message' => __('Sorry, your nonce did not verify.', 'injection-guard')], 400);
275 }
276
277 // Only allow super admins
278 if (!is_super_admin()) {
279 wp_send_json_error(['message' => __('Unauthorized action.', 'injection-guard')], 403);
280 }
281
282 // Sanitize posted data with depth-safe function
283 $posted_data = sanitize_ig_data($_POST);
284
285 $ig_type = $posted_data['ig_type'] ?? 'blacklist';
286 $ig_post_obj = $posted_data['ig_post_obj'] ?? [];
287
288 $guard_obj = new guard_wordpress;
289
290 if (!empty($ig_post_obj)) {
291 foreach ($ig_post_obj as $uri => $val_array) {
292 if (!empty($val_array)) {
293 foreach ($val_array as $val) {
294 if ($ig_type === 'whitelist') {
295 $guard_obj->update_blacklisted($val, $uri, false);
296 } else {
297 $guard_obj->update_blacklisted($val, $uri, true);
298 }
299 }
300 }
301 }
302 }
303
304 wp_send_json_success(['message' => __('Updated successfully.', 'injection-guard')]);
305 }
306 }
307
308 add_action( 'wp_login', function( $user_login, $user ) {
309 update_user_meta( $user->ID, 'ig_last_login', time() );
310 update_user_meta( $user->ID, 'ig_session_start', time() );
311 }, 10, 2 );
312
313 add_action( 'wp_logout', function() {
314 $user_id = get_current_user_id();
315 if ( $user_id ) {
316 $start = get_user_meta( $user_id, 'ig_session_start', true );
317 $end = time();
318
319 if ( $start ) {
320 $duration = $end - $start;
321 update_user_meta( $user_id, 'ig_last_session_duration', $duration );
322 update_user_meta( $user_id, 'ig_last_logout', $end );
323 }
324 }
325 });
326
327 add_filter( 'manage_users_columns', function( $columns ) {
328 $columns['ig_last_login'] = __( 'Last Login', 'injection-guard' );
329 $columns['ig_last_logout'] = __( 'Last Logout', 'injection-guard' );
330 $columns['ig_session_length'] = __( 'Session Duration', 'injection-guard' );
331 return $columns;
332 } );
333
334 add_filter( 'manage_users_custom_column', function( $value, $column_name, $user_id ) {
335 if ( $column_name === 'ig_last_login' ) {
336 $login = get_user_meta( $user_id, 'ig_last_login', true );
337 $start = get_user_meta( $user_id, 'ig_session_start', true );
338 $display = $login ?: $start;
339 return $display ? date( 'Y-m-d H:i:s', $display ) : '';
340 }
341
342 if ( $column_name === 'ig_last_logout' ) {
343 $logout = get_user_meta( $user_id, 'ig_last_logout', true );
344 return $logout ? date( 'Y-m-d H:i:s', $logout ) : '';
345 }
346
347 if ( $column_name === 'ig_session_length' ) {
348 $start = get_user_meta( $user_id, 'ig_session_start', true );
349 $last_seen = get_user_meta( $user_id, 'ig_last_seen', true );
350 if ( $start && $last_seen && $last_seen > $start ) {
351 $duration = $last_seen - $start;
352 return gmdate( 'H:i:s', $duration );
353 }
354 return '';
355 }
356
357 return $value;
358 }, 10, 3 );
359
360
361
362
363 function ig_capability_audit_page() {
364 if ( ! current_user_can( 'manage_options' ) ) {
365 wp_die( __( 'You are not allowed to access this page.', 'injection-guard' ) );
366 }
367 ?>
368 <div class="wrap">
369 <h1><?php _e( 'Capability Audit', 'injection-guard' ); ?> &#128462;</h1>
370 <table id="cap-audit-table">
371 <thead>
372 <tr>
373 <th><?php _e( 'ID', 'injection-guard' ); ?></th>
374 <th><?php _e( 'Username', 'injection-guard' ); ?></th>
375 <th><?php _e( 'Email', 'injection-guard' ); ?></th>
376 <th><?php _e( 'Capabilities', 'injection-guard' ); ?></th>
377 </tr>
378 </thead>
379
380 <tbody id="cap-audit-results"></tbody>
381 </table>
382
383 </div>
384 <?php
385 }
386
387 add_action('wp_ajax_ig_load_capability_audit', function() {
388 if ( ! current_user_can( 'manage_options' ) ) {
389 wp_send_json_error( 'Unauthorized', 403 );
390 }
391
392 check_ajax_referer( 'ig_nonce_action', 'security' );
393
394
395 global $wpdb;
396 $offset = intval($_GET['offset'] ?? 0);
397 $per_page = intval($_GET['per_page'] ?? 100);
398 $cap_key = $wpdb->prefix . 'capabilities';
399
400 $results = $wpdb->get_results( $wpdb->prepare("
401 SELECT u.ID as user_id, u.user_login, u.user_email, um.meta_value as caps
402 FROM {$wpdb->users} u
403 INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID
404 WHERE um.meta_key = %s
405 ORDER BY u.ID ASC
406 LIMIT %d OFFSET %d
407 ", $cap_key, $per_page, $offset) );
408
409 if ( $offset === 0 ) {
410 echo '<style>table { border-collapse: collapse; width: 100%; margin-top: 1em; } td, th { border: 1px solid #ccc; padding: 6px; font-size: 13px; } .flag { background: #fff3f3; color: #b00; font-weight: bold; }</style>';
411 }
412
413 foreach ( $results as $row ) {
414 $caps = maybe_unserialize( $row->caps );
415 $cap_list = [];
416 $suspicious = false;
417
418 foreach ( (array) $caps as $cap => $value ) {
419 if ( $value ) {
420 $cap_list[] = $cap;
421 if ( in_array( $cap, [ 'manage_options', 'edit_users', 'install_plugins', 'delete_users' ] ) ) {
422 $suspicious = true;
423 }
424 }
425 }
426
427 $user_link = admin_url("user-edit.php?user_id={$row->user_id}");
428 $class = ($suspicious || trim($row->user_login, '-') === '') ? 'flag' : '';
429
430 echo "<tr class='{$class}'>";
431 echo "<td><a href='" . esc_url($user_link) . "' target='_blank'>" . esc_html($row->user_id) . "</a></td>";
432 echo "<td>" . esc_html($row->user_login) . "</td>";
433 echo "<td>" . esc_html($row->user_email) . "</td>";
434 echo "<td>" . esc_html(implode(', ', $cap_list ?: [''])) . "</td>";
435 echo "</tr>";
436 }
437
438 wp_die();
439 });
440
441 add_action( 'init', 'ig_track_user_session_ping', 1 );
442 add_action( 'admin_init', 'ig_track_user_session_ping', 1 );
443
444 function ig_track_user_session_ping() {
445 if ( ! is_user_logged_in() ) return;
446
447 $user_id = get_current_user_id();
448 $now = time();
449
450 $start = get_user_meta( $user_id, 'ig_session_start', true );
451 $last_seen = get_user_meta( $user_id, 'ig_last_seen', true );
452
453 if ( empty( $start ) || ! is_numeric( $start ) || $start > $now ) {
454 update_user_meta( $user_id, 'ig_session_start', $now );
455 update_user_meta( $user_id, 'ig_last_seen', $now );
456 update_user_meta( $user_id, 'ig_last_session_duration', 0 );
457 return;
458 }
459
460 if ( empty( $last_seen ) || ( $now - intval( $last_seen ) ) >= 300 ) {
461 update_user_meta( $user_id, 'ig_last_seen', $now );
462 update_user_meta( $user_id, 'ig_last_session_duration', $now - intval( $start ) );
463 }
464 }
465