Headline
CVE-2020-36668: Changeset 2348984 for backup – WordPress Plugin Repository
The JetBackup – WP Backup, Migrate & Restore plugin for WordPress is vulnerable to sensitive information disclosure in versions up to, and including, 1.4.0 due to a lack of proper capability checking on the backup_guard_get_manual_modal function called via an AJAX action. This makes it possible for subscriber-level attackers, and above, to invoke the function and obtain database table information.
backup/trunk/BackupGuard.php
r2341420
r2348984
338
338
{
339
339
check\_ajax\_referer('backupGuardAjaxNonce', 'token');
340
if (is\_admin()) {
340
if (current\_user\_can( 'activate\_plugins' )) {
341
341
require\_once(SG\_PUBLIC\_AJAX\_PATH.'modalManualBackup.php');
342
342
}
…
…
404
404
add\_action('wp\_ajax\_backup\_guard\_checkBackupCreation', 'backup\_guard\_check\_backup\_creation');
405
405
add\_action('wp\_ajax\_backup\_guard\_checkRestoreCreation', 'backup\_guard\_check\_restore\_creation');
406
add\_action('wp\_ajax\_backup\_guard\_cloudDropbox', 'backup\_guard\_cloud\_dropbox');
407
add\_action('wp\_ajax\_backup\_guard\_cloudGdrive', 'backup\_guard\_cloud\_gdrive');
408
add\_action('wp\_ajax\_backup\_guard\_cloudOneDrive', 'backup\_guard\_cloud\_oneDrive');
409
add\_action('wp\_ajax\_backup\_guard\_cloudFtp', 'backup\_guard\_cloud\_ftp');
410
add\_action('wp\_ajax\_backup\_guard\_cloudAmazon', 'backup\_guard\_cloud\_amazon');
406
add\_action('wp\_ajax\_backup\_guard\_cloudDropbox', 'backup\_guard\_cloud\_dropbox');
407
408
$pluginCapabilities = backupGuardGetCapabilities();
409
if ($pluginCapabilities != BACKUP\_GUARD\_CAPABILITIES\_FREE) {
410
require\_once dirname(\_\_FILE\_\_).'/BackupGuardPro.php';
411
}
411
412
add\_action('wp\_ajax\_backup\_guard\_curlChecker', 'backup\_guard\_curl\_checker');
412
413
add\_action('wp\_ajax\_backup\_guard\_deleteBackup', 'backup\_guard\_delete\_backup');
…
…
503
504
add_action('wp_ajax_nopriv_backup_guard_awake’, ‘backup_guard_awake_nopriv’);
504
505
add_action('admin_post_backup_guard_cloudDropbox’, ‘backup_guard_cloud_dropbox’);
505
add_action('admin_post_backup_guard_cloudGdrive’, ‘backup_guard_cloud_gdrive’);
506
add_action('admin_post_backup_guard_cloudOneDrive’, ‘backup_guard_cloud_oneDrive’);
507
508
function backup_guard_cloud_oneDrive()
509
{
510
require\_once(SG\_PUBLIC\_AJAX\_PATH.'cloudOneDrive.php');
511
}
512
506
513
507
function backup_guard_import_key_file()
…
…
577
571
function backup_guard_cloud_dropbox()
578
572
{
579
check\_ajax\_referer('backupGuardAjaxNonce', 'token');
580
require\_once(SG\_PUBLIC\_AJAX\_PATH.'cloudDropbox.php');
581
}
582
583
function backup_guard_cloud_ftp()
584
{
585
require\_once(SG\_PUBLIC\_AJAX\_PATH.'cloudFtp.php');
586
}
587
588
function backup_guard_cloud_amazon()
589
{
590
check\_ajax\_referer('backupGuardAjaxNonce', 'token');
591
require\_once(SG\_PUBLIC\_AJAX\_PATH.'cloudAmazon.php');
592
}
593
594
function backup_guard_cloud_gdrive()
595
{
596
check\_ajax\_referer('backupGuardAjaxNonce', 'token');
597
require\_once(SG\_PUBLIC\_AJAX\_PATH.'cloudGdrive.php');
573
if (current\_user\_can('activate\_plugins')) {
574
check\_ajax\_referer('backupGuardAjaxNonce', 'token');
575
require\_once(SG\_PUBLIC\_AJAX\_PATH . 'cloudDropbox.php');
576
}
598
577
}
599
578
…
…
731
710
backup\_guard\_register\_ajax\_callbacks();
732
711
// backupGuardPluginRedirect();
733
712
734
713
//check if database should be updated
735
714
if (backupGuardShouldUpdate()) {
…
…
748
727
749
728
function sgBackupAdminInit() {
750
//load pro plugin updater
751
$pluginCapabilities = backupGuardGetCapabilities();
752
$isLoggedIn = is\_user\_logged\_in();
753
754
if ($pluginCapabilities != BACKUP\_GUARD\_CAPABILITIES\_FREE && $isLoggedIn) {
755
require\_once(dirname(\_\_FILE\_\_).'/plugin-update-checker/plugin-update-checker.php');
756
require\_once(dirname(\_\_FILE\_\_).'/plugin-update-checker/Puc/v4/Utils.php');
757
require\_once(SG\_LIB\_PATH.'SGAuthClient.php');
758
759
$licenseKey = SGConfig::get('SG\_LICENSE\_KEY');
760
761
$updateChecker = Puc\_v4\_Factory::buildUpdateChecker(
762
BackupGuard\\Config::URL.'/products/details/'.$licenseKey,
763
SG\_BACKUP\_GUARD\_MAIN\_FILE,
764
SG\_PRODUCT\_IDENTIFIER
765
);
766
767
$updateChecker->addHttpRequestArgFilter(array(
768
SGAuthClient::getInstance(),
769
'filterUpdateChecks'
770
));
771
}
729
//load pro plugin updater
730
$pluginCapabilities = backupGuardGetCapabilities();
731
$isLoggedIn = is\_user\_logged\_in();
732
733
if ($pluginCapabilities != BACKUP\_GUARD\_CAPABILITIES\_FREE && $isLoggedIn) {
734
require\_once(dirname(\_\_FILE\_\_).'/plugin-update-checker/plugin-update-checker.php');
735
require\_once(dirname(\_\_FILE\_\_).'/plugin-update-checker/Puc/v4/Utils.php');
736
require\_once(SG\_LIB\_PATH.'SGAuthClient.php');
737
738
$licenseKey = SGConfig::get('SG\_LICENSE\_KEY');
739
740
$updateChecker = Puc\_v4\_Factory::buildUpdateChecker(
741
BackupGuard\\Config::URL.'/products/details/'.$licenseKey,
742
SG\_BACKUP\_GUARD\_MAIN\_FILE,
743
SG\_PRODUCT\_IDENTIFIER
744
);
745
746
$updateChecker->addHttpRequestArgFilter(array(
747
SGAuthClient::getInstance(),
748
'filterUpdateChecks'
749
));
750
}
772
751
}
773
752
backup/trunk/README.txt
r2341420
r2348984
7
7
Requires at least: 3.8
8
8
Tested up to: 5.4.2
9
Stable tag: 1.4.0
9
Stable tag: 1.4.1
10
10
License: GPLv2 or later
11
11
License URI: http://www.gnu.org/licenses/gpl-2.0.html
…
…
61
61
See <strong>BackupGuard Pro</strong> in action here: <a href="https://www.youtube.com/watch?v=TSPgmrSu-ls">https://www.youtube.com/watch?v=TSPgmrSu-ls</a>
62
62
63
<h4>A special note on WordPress migration</h4>
63
<h4>A SPECIAL NOTE ON WORDPRESS MIGRATION/h4>
64
64
65
65
A WordPress site migration is an easy task if performed properly. There are three different migration scenarios:
…
…
70
70
</ul>
71
71
72
Backup Guard Pro helps you to migrate in all of these cases in the smoothest possible way. You just have to Backup your site and Restore it in the new location. No additional work will be required, since we handle all changes for you.
73
74
The issues that users always deal with are: wrong site url, images don’t load, dashboard not accessible, permalinks don’t work and more.
75
76
Backup Guard Pro will help you to skip all these problems, because of its advanced refactoring and migrating engine.
72
Backup Guard free version will help you migrate your website in case there is no change in the domain or the Database prefix.
73
If there is any change in the domain or the DB prefix, Backup Guard Pro will be of use.
74
75
Backup Guard Pro helps you to migrate in all of the above mentioned three cases in the smoothest possible way. You just have to Backup your site and Restore it in the new location. No additional work will be required, since we handle all changes for you.
76
77
The issues that users always deal with are: wrong site URL, images not loading, dashboard not being accessible, permalinks not working and more.
78
79
Backup Guard Pro will help you to skip all these problems because of its advanced refactoring and migrating engine.
77
80
78
81
<h4>Documentation</h4>
…
…
109
112
</ul>
110
113
114
= Does Backup Guard provide migration with the free version? =
115
116
It is possible to use migration with the free version if:
117
1. There is no change in the domain.
118
2. There is no change in the Database prefix.
119
Please note that even a single symbol change counts as a migration that should be done with the Pro version
120
111
121
= Can I use BackupGuard to migrate a website? =
112
122
…
…
158
168
159
169
== Changelog ==
170
= 1.4.1 =
171
* Security improvement
172
* Some environment checks were carried out which ensure that the plugin works seamlessly. The mentioned checks are necessary for the plugin to work as intended.
173
160
174
= 1.4.0 =
161
175
* Plugin security improvements
backup/trunk/backup.php
r2341420
r2348984
5
5
* Plugin URI: https://backup-guard.com/products/backup-wordpress
6
6
* Description: Backup Guard is the most complete site backup and restore plugin. We offer the easiest way to backup, restore or migrate your site. You can backup your files, database or both.
7
* Version: 1.4.0
7
* Version: 1.4.1
8
8
* Author: BackupGuard
9
9
* Author URI: https://backup-guard.com/products/backup-wordpress
…
…
17
17
18
18
if (!defined(‘SG_BACKUP_GUARD_VERSION’)) {
19
define('SG\_BACKUP\_GUARD\_VERSION', '1.4.0');
19
define('SG\_BACKUP\_GUARD\_VERSION', '1.4.1');
20
20
}
21
21
backup/trunk/com/core/SGBoot.php
r2309221
r2348984
72
72
private static function installConfigTable($sgdb)
73
73
{
74
//drop config table
75
$sgdb->query('DROP TABLE IF EXISTS \`'.SG\_CONFIG\_TABLE\_NAME.'\`;');
76
74
$dbEngine = backupGuardGetDatabaseEngine();
77
75
//create config table
78
76
$res = $sgdb->query(
…
…
81
79
\`cvalue\` text NOT NULL,
82
80
PRIMARY KEY (\`ckey\`)
83
) DEFAULT CHARSET=utf8;'
81
) ENGINE='.$dbEngine.' DEFAULT CHARSET=utf8;'
84
82
);
85
83
if ($res===false) {
…
…
110
108
private static function installScheduleTable($sgdb)
111
109
{
112
//drop schedule table
113
$sgdb->query('DROP TABLE IF EXISTS \`'.SG\_SCHEDULE\_TABLE\_NAME.'\`;');
110
$dbEngine = backupGuardGetDatabaseEngine();
114
111
115
112
//create schedule table
…
…
122
119
\`backup\_options\` text NOT NULL,
123
120
PRIMARY KEY (\`id\`)
124
) DEFAULT CHARSET=utf8;'
121
) ENGINE='.$dbEngine.' DEFAULT CHARSET=utf8;'
125
122
);
126
123
if ($res===false) {
…
…
133
130
private static function installActionTable($sgdb)
134
131
{
135
//drop action table
136
$sgdb->query('DROP TABLE IF EXISTS \`'.SG\_ACTION\_TABLE\_NAME.'\`;');
132
$dbEngine = backupGuardGetDatabaseEngine();
137
133
138
134
//create action table
…
…
149
145
\`options\` text NOT NULL,
150
146
PRIMARY KEY (\`id\`)
151
) DEFAULT CHARSET=utf8;"
147
) ENGINE=".$dbEngine." DEFAULT CHARSET=utf8;"
152
148
);
153
149
if ($res===false) {
backup/trunk/com/core/functions.php
r2309221
r2348984
724
724
}
725
725
726
function checkAllMissedTables()
727
{
728
$sgdb = SGDatabase::getInstance();
729
$allTables = array(SG\_CONFIG\_TABLE\_NAME, SG\_SCHEDULE\_TABLE\_NAME, SG\_ACTION\_TABLE\_NAME);
730
$missedTables = array();
731
$status = true;
732
733
foreach ($allTables as $table) {
734
$query = $sgdb->query("SELECT count(\*) as isExists
735
FROM information\_schema.TABLES
736
WHERE (TABLE\_SCHEMA = '".DB\_NAME."') AND (TABLE\_NAME = '$table')"
737
);
738
739
if (empty($query\[0\]\['isExists'\])) {
740
$status = false;
741
}
742
}
743
744
return $status;
745
}
746
726
747
function backupGuardIncludeFile($filePath)
727
748
{
backup/trunk/com/core/notice/SGNoticeHandler.php
r2246797
r2348984
9
9
$this->checkRestoreNotWritableError();
10
10
$this->checkLiteSpeedWarning();
11
$this->checkTables();
12
$this->checkPingFilePermission();
11
13
}
12
14
…
…
21
23
SGNotice::getInstance()->addNoticeFromTemplate('timeout\_free\_error', SG\_NOTICE\_ERROR, true);
22
24
}
25
}
26
}
27
28
public function checkTables()
29
{
30
if (!checkAllMissedTables()) {
31
SGNotice::getInstance()->addNoticeFromTemplate('missed\_table', SG\_NOTICE\_ERROR, true);
23
32
}
24
33
}
…
…
60
69
}
61
70
}
71
72
private function checkPingFilePermission()
73
{
74
if (file\_exists(SG\_PING\_FILE\_PATH) && !is\_readable(SG\_PING\_FILE\_PATH)) {
75
SGNotice::getInstance()->addNoticeFromTemplate('ping\_permission', SG\_NOTICE\_ERROR, true);
76
}
77
}
62
78
}
backup/trunk/public/include/functions.php
r2246797
r2348984
224
224
return SG\_FORCE\_DB\_TABLES\_RESET;
225
225
}
226
227
if (!checkAllMissedTables()) {
228
return true;
229
}
226
230
227
231
return false;
232
}
233
234
function backupGuardGetDatabaseEngine()
235
{
236
global $wpdb;
237
$dbName = $wpdb->dbname;
238
$engine = 'InnoDB';
239
$engineCheckSql = "SELECT ENGINE FROM information\_schema.TABLES WHERE TABLE\_SCHEMA = '$dbName'";
240
$result = $wpdb->get\_results($engineCheckSql, ARRAY\_A);
241
if (!empty($result)) {
242
$engineCheckSql = "SHOW TABLE STATUS WHERE Name = '".$wpdb->prefix."users' AND Engine = 'MyISAM'";
243
$result = $wpdb->get\_results($engineCheckSql, ARRAY\_A);
244
if (isset($result\[0\]\['Engine'\]) && $result\[0\]\['Engine'\] == 'MyISAM') {
245
$engine = 'MyISAM';
246
}
247
}
248
249
return $engine;
228
250
}
229
251
backup/trunk/public/services.php
r2313492
r2348984
17
17
<ul class="plugin-action-buttons">
18
18
<li>
19
<p id="sg-migration-service-price"><b>$59.95</b></p>
19
<p id="sg-migration-service-price"><b>$84.95</b></p>
20
20
</li>
21
21
<li>