Headline
CVE-2021-25108: Changeset 2653459 – WordPress Plugin Repository
The IP2Location Country Blocker WordPress plugin before 2.26.6 does not have CSRF check in the ip2location_country_blocker_save_rules AJAX action, allowing attackers to make a logged in admin block arbitrary country, or block all of them at once, preventing users from accessing the frontend.
ip2location-country-blocker/trunk/assets/js/settings.js
r2629572
r2653459
23
23
action: 'ip2location\_country\_blocker\_update\_ip2location\_database',
24
24
token: $('#download\_token').val(),
25
ipv4\_only: ipv4\_only
25
ipv4\_only: ipv4\_only,
26
\_\_nonce: $('#update\_nonce').val(),
26
27
}, function (data) {
27
28
if (data.status == 'OK') {
…
…
66
67
action: 'ip2location\_country\_blocker\_update\_ip2proxy\_database',
67
68
token: $('#px\_download\_token').val(),
68
ipv4\_only: ipv4\_only
69
ipv4\_only: ipv4\_only,
70
\_\_nonce: $('#update\_nonce').val(),
69
71
}, function (data) {
70
72
if (data.status == 'OK') {
…
…
104
106
$.post(ajaxurl, {
105
107
action: 'ip2location\_country\_blocker\_validate\_token',
106
token: $('#setup\_token').val()
108
token: $('#setup\_token').val(),
109
\_\_nonce: $('#update\_nonce').val(),
107
110
}, function (data) {
108
111
if (data.status == 'OK') {
…
…
118
121
action: 'ip2location\_country\_blocker\_update\_ip2location\_database',
119
122
token: $('#setup\_token').val(),
120
ipv4\_only: true
123
ipv4\_only: true,
124
\_\_nonce: $('#update\_nonce').val(),
121
125
}, function (data) {
122
126
if (data.status == 'OK') {
ip2location-country-blocker/trunk/ip2location-country-blocker.php
r2652469
r2653459
4
4
* Plugin URI: https://ip2location.com/resources/wordpress-ip2location-country-blocker
5
5
* Description: Block visitors from accessing your website or admin area by their country.
6
* Version: 2.26.5
6
* Version: 2.26.6
7
7
* Author: IP2Location
8
8
* Author URI: https://www.ip2location.com.
…
…
31
31
add_action('wp_ajax_ip2location_country_blocker_update_ip2proxy_database’, [$ip2location_country_blocker, ‘update_ip2proxy_database’]);
32
32
add_action('wp_ajax_ip2location_country_blocker_validate_token’, [$ip2location_country_blocker, ‘validate_token’]);
33
add_action('wp_ajax_ip2location_country_blocker_save_rules’, [$ip2location_country_blocker, ‘save_rules’]);
34
33
add_action('wp_footer’, [$ip2location_country_blocker, ‘footer’]);
35
34
add_action('wp_ajax_ip2location_country_blocker_submit_feedback’, [$ip2location_country_blocker, ‘submit_feedback’]);
…
…
117
116
118
117
if (isset($\_POST\['submit'\])) {
118
check\_admin\_referer('save-frontend');
119
119
120
if (!isset($\_POST\['frontend\_block\_proxy\_type'\])) {
120
121
$frontend\_block\_proxy\_type = '';
…
…
182
183
183
184
<form method="post" novalidate="novalidate">
185
' . wp\_nonce\_field('save-frontend') . '
184
186
<div style="margin-top:20px">
185
187
<label for="enable\_frontend">
…
…
411
413
412
414
if (isset($\_POST\['submit'\])) {
415
check\_admin\_referer('save-backend');
416
413
417
if (!isset($\_POST\['backend\_block\_proxy\_type'\])) {
414
418
$backend\_block\_proxy\_type = '';
…
…
479
483
480
484
<form id="form\_backend\_settings" method="post" novalidate="novalidate">
485
' . wp\_nonce\_field('save-backend') . '
481
486
<input type="hidden" name="my\_country\_code" id="my\_country\_code" value="' . $my\_country\_code . '" />
482
487
<input type="hidden" name="my\_country\_name" id="my\_country\_name" value="' . $my\_country\_name . '" />
…
…
713
718
714
719
if (isset($\_POST\['purge'\])) {
720
check\_admin\_referer('purge-logs');
721
715
722
$GLOBALS\['wpdb'\]->query('TRUNCATE TABLE ' . $GLOBALS\['wpdb'\]->prefix . 'ip2location\_country\_blocker\_log');
716
723
}
…
…
867
874
<p>
868
875
<form id="form-purge" method="post">
876
' . wp\_nonce\_field('purge-logs') . '
869
877
<input type="hidden" name="purge" value="true">
870
878
<input type="submit" name="submit" id="btn-purge" class="button button-primary" value="Purge All Logs" />
…
…
970
978
971
979
if (isset($\_POST\['submit'\])) {
980
check\_admin\_referer('ip-lookup');
981
972
982
$this->cache\_flush();
973
983
…
…
1008
1018
1009
1019
<form method="post" novalidate="novalidate">
1020
' . wp\_nonce\_field('ip-lookup') . '
1010
1021
<table class="form-table">
1011
1022
<tr>
…
…
1044
1055
1045
1056
if (isset($\_POST\['lookup\_mode'\])) {
1057
check\_admin\_referer('settings');
1058
1046
1059
if (empty($api\_key)) {
1047
1060
$lookup\_mode = 'bin';
…
…
1156
1169
1157
1170
<form action="' . get\_admin\_url() . 'admin.php?page=ip2location-country-blocker-settings" method="post" novalidate="novalidate">
1171
' . wp\_nonce\_field('settings') . '
1158
1172
<table class="form-table">
1159
1173
<tr>
…
…
1595
1609
</div>';
1596
1610
}
1611
1612
$nonce = wp\_create\_nonce('update-database');
1613
1614
echo '<input type="hidden" id="update\_nonce" value="' . $nonce . '">';
1597
1615
}
1598
1616
…
…
1888
1906
@set\_time\_limit(300);
1889
1907
1908
check\_ajax\_referer('update-database', '\_\_nonce');
1909
1890
1910
header('Content-Type: application/json');
1891
1911
…
…
2048
2068
@set\_time\_limit(300);
2049
2069
2070
check\_ajax\_referer('update-database', '\_\_nonce');
2071
2050
2072
header('Content-Type: application/json');
2051
2073
…
…
2260
2282
\]));
2261
2283
}
2262
}
2263
2264
public function save\_rules()
2265
{
2266
if (!current\_user\_can('administrator')) {
2267
wp\_die(\_\_('Permission denied.', 'ip2location-country-blocker'));
2268
}
2269
2270
$mode = (isset($\_POST\['mode'\])) ? $\_POST\['mode'\] : '';
2271
$countries = (isset($\_POST\['countries'\])) ? $\_POST\['countries'\] : '';
2272
2273
$countries = (!is\_array($countries)) ? \[$countries\] : $countries;
2274
2275
// Remove country that existed in group to prevent duplicated lookup.
2276
$removed\_list = \[\];
2277
if (($groups = $this->get\_group\_from\_list($countries)) !== false) {
2278
foreach ($groups as $group) {
2279
foreach ($countries as $country\_code) {
2280
if ($this->is\_in\_array($country\_code, $this->country\_groups\[$group\])) {
2281
if (($key = array\_search($country\_code, $countries)) !== false) {
2282
$removed\_list\[\] = $this->get\_country\_name($country\_code);
2283
unset($countries\[$key\]);
2284
}
2285
}
2286
}
2287
}
2288
}
2289
2290
update\_option('ip2location\_country\_blocker\_frontend\_enabled', 1);
2291
update\_option('ip2location\_country\_blocker\_frontend\_block\_mode', $mode);
2292
update\_option('ip2location\_country\_blocker\_frontend\_banlist', $countries);
2293
update\_option('ip2location\_country\_blocker\_frontend\_option', 1);
2294
2284
}
2295
2285
ip2location-country-blocker/trunk/readme.txt
r2652469
r2653459
6
6
Requires at least: 2.0
7
7
Tested up to: 5.8
8
Stable tag: 2.26.5
8
Stable tag: 2.26.6
9
9
10
10
Blocks unwanted visitors from accessing your frontend (blog pages) or backend (admin area) by countries or proxy servers.
…
…
89
89
90
90
== Changelog ==
91
* 2.26.6 Improved security against CSRF by adding nonces.
91
92
* 2.26.5 Fixed security issues with CSRF.
92
93
* 2.26.4 Removed missing Javascript.