Skip to content

Commit ceb9632

Browse files
chore: add nonce check to license form, limit autocomplete results to 25, unschedule event on plugin deactivation
1 parent 1e1e411 commit ceb9632

5 files changed

Lines changed: 51 additions & 11 deletions

File tree

boxzilla.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
// register activation hook
4848
register_activation_hook(__FILE__, [ 'Boxzilla\\Admin\\Installer', 'run' ]);
49+
register_deactivation_hook(__FILE__, [ 'Boxzilla\\Licensing\\Poller', 'deactivate' ]);
4950

5051
// Bootstrap plugin at later action hook
5152
add_action(

src/admin/class-autocomplete.php

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
class Autocomplete
1010
{
11+
private const MAX_RESULTS = 20;
12+
1113
public function init(): void
1214
{
1315
add_action('wp_ajax_boxzilla_autocomplete', [ $this, 'ajax' ], 10, 0);
@@ -22,13 +24,17 @@ public function ajax(): void
2224
wp_die('', '', [ 'response' => 403 ]);
2325
}
2426

25-
$q = ( isset($_GET['q']) ) ? sanitize_text_field($_GET['q']) : '';
26-
$type = ( isset($_GET['type']) && in_array($_GET['type'], [ 'page', 'post', 'category', 'post_type', 'post_tag' ], true) ) ? $_GET['type'] : 'post';
27+
$q = isset($_GET['q']) ? sanitize_text_field(wp_unslash($_GET['q'])) : '';
28+
$allowed_types = [ 'page', 'post', 'category', 'post_type', 'post_tag' ];
29+
$type = isset($_GET['type']) ? sanitize_key(wp_unslash($_GET['type'])) : '';
30+
if (! in_array($type, $allowed_types, true)) {
31+
$type = 'post';
32+
}
2733

2834
// do nothing if supplied 'q' parameter is omitted or empty
2935
// or less than 2 characters long
3036
if (empty($q) || strlen($q) < 2) {
31-
die();
37+
wp_die();
3238
}
3339

3440
switch ($type) {
@@ -51,7 +57,7 @@ public function ajax(): void
5157
break;
5258
}
5359

54-
die();
60+
wp_die();
5561
}
5662

5763
/**
@@ -64,13 +70,15 @@ protected function list_posts($query, $post_type = 'post')
6470
{
6571
global $wpdb;
6672
$like = $wpdb->esc_like($query) . '%';
73+
$limit = self::MAX_RESULTS;
6774

6875
$post_slugs = $wpdb->get_col(
6976
$wpdb->prepare(
70-
"SELECT p.post_name FROM $wpdb->posts p WHERE p.post_type = %s AND p.post_status = 'publish' AND ( p.post_title LIKE %s OR p.post_name LIKE %s ) GROUP BY p.post_name",
77+
"SELECT p.post_name FROM $wpdb->posts p WHERE p.post_type = %s AND p.post_status = 'publish' AND ( p.post_title LIKE %s OR p.post_name LIKE %s ) GROUP BY p.post_name ORDER BY p.post_name ASC LIMIT %d",
7178
$post_type,
7279
$like,
73-
$like
80+
$like,
81+
$limit
7482
)
7583
);
7684
return join(PHP_EOL, $post_slugs);
@@ -86,9 +94,15 @@ protected function list_categories($query)
8694
$terms = get_terms([
8795
'taxonomy' => 'category',
8896
'name__like' => $query,
97+
'number' => self::MAX_RESULTS,
8998
'fields' => 'names',
9099
'hide_empty' => false,
91100
]);
101+
102+
if (is_wp_error($terms)) {
103+
return '';
104+
}
105+
92106
return join(PHP_EOL, $terms);
93107
}
94108

@@ -102,9 +116,15 @@ protected function list_tags($query)
102116
$terms = get_terms([
103117
'taxonomy' => 'post_tag',
104118
'name__like' => $query,
119+
'number' => self::MAX_RESULTS,
105120
'fields' => 'names',
106121
'hide_empty' => false,
107122
]);
123+
124+
if (is_wp_error($terms)) {
125+
return '';
126+
}
127+
108128
return join(PHP_EOL, $terms);
109129
}
110130

@@ -124,6 +144,8 @@ function ($name) use ($query) {
124144
}
125145
);
126146

147+
$matched_post_types = array_slice($matched_post_types, 0, self::MAX_RESULTS);
148+
127149
return join(PHP_EOL, $matched_post_types);
128150
}
129151
}

src/licensing/class-license-manager.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,20 @@ protected function listen()
108108
return;
109109
}
110110

111-
$action = isset($_POST['action']) ? $_POST['action'] : 'activate';
111+
$nonce = isset($_POST['boxzilla_license_nonce']) ? sanitize_text_field(wp_unslash($_POST['boxzilla_license_nonce'])) : '';
112+
if (! wp_verify_nonce($nonce, 'boxzilla_license_form_action')) {
113+
$this->notices[] = [
114+
'type' => 'warning',
115+
'message' => esc_html__('Security check failed. Please refresh the page and try again.', 'boxzilla'),
116+
];
117+
return;
118+
}
119+
120+
$action = isset($_POST['action']) ? sanitize_text_field(wp_unslash($_POST['action'])) : 'activate';
112121
$key_changed = false;
113122

114123
// did key change or was "activate" button pressed?
115-
$new_license_key = sanitize_text_field($_POST['boxzilla_license_key']);
124+
$new_license_key = isset($_POST['boxzilla_license_key']) ? sanitize_text_field(wp_unslash($_POST['boxzilla_license_key'])) : '';
116125
if ($new_license_key !== $this->license->key) {
117126
$this->license->key = $new_license_key;
118127
$key_changed = true;

src/licensing/class-poller.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
class Poller
1010
{
11+
public const HOOK = 'boxzilla_check_license_status';
12+
1113
/**
1214
* @var API
1315
*/
@@ -35,11 +37,16 @@ public function __construct(API $api, License $license)
3537
*/
3638
public function init()
3739
{
38-
if (! wp_next_scheduled('boxzilla_check_license_status')) {
39-
wp_schedule_event(time(), 'daily', 'boxzilla_check_license_status');
40+
if (! wp_next_scheduled(self::HOOK)) {
41+
wp_schedule_event(time(), 'daily', self::HOOK);
4042
}
4143

42-
add_action('boxzilla_check_license_status', [ $this, 'run' ]);
44+
add_action(self::HOOK, [ $this, 'run' ]);
45+
}
46+
47+
public static function deactivate()
48+
{
49+
wp_clear_scheduled_hook(self::HOOK);
4350
}
4451

4552
/**

src/licensing/views/license-form.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<?php } ?>
4242

4343
<form method="post">
44+
<?php wp_nonce_field('boxzilla_license_form_action', 'boxzilla_license_nonce'); ?>
4445
<table class="form-table">
4546
<tr valign="top">
4647
<th><?php esc_html_e('License Key', 'boxzilla'); ?></th>

0 commit comments

Comments
 (0)