Headline
CVE-2019-25141: Diff [2052057:2052058] for easy-wp-smtp – WordPress Plugin Repository
The Easy WP SMTP plugin for WordPress is vulnerable to authorization bypass in versions up to, and including, 1.3.9. This is due to missing capability checks on the admin_init() function, in addition to insufficient input validation. This makes it possible for unauthenticated attackers to modify the plugins settings and arbitrary options on the site that can be used to inject new administrative user accounts.
easy-wp-smtp/trunk/easy-wp-smtp.php
r2052057
r2052058
2
2
/*
3
3
Plugin Name: Easy WP SMTP
4
Version: 1.3.9
4
Version: 1.3.9.1
5
5
Plugin URI: https://wp-ecommerce.net/easy-wordpress-smtp-send-emails-from-your-wordpress-site-using-a-smtp-server-2197
6
6
Author: wpecommerce, alexanderfoxc
…
…
250
250
251
251
function admin\_init() {
252
if ( defined( 'DOING\_AJAX' ) && DOING\_AJAX ) {
253
add\_action( 'wp\_ajax\_swpsmtp\_clear\_log', array( $this, 'clear\_log' ) );
254
add\_action( 'wp\_ajax\_swpsmtp\_self\_destruct', array( $this, 'self\_destruct\_handler' ) );
255
}
256
//view log file
257
if ( isset( $\_GET\[ 'swpsmtp\_action' \] ) ) {
258
if ( $\_GET\[ 'swpsmtp\_action' \] === 'view\_log' ) {
259
$log\_file\_name = $this->opts\[ 'smtp\_settings' \]\[ 'log\_file\_name' \];
260
if ( ! file\_exists( plugin\_dir\_path( \_\_FILE\_\_ ) . $log\_file\_name ) ) {
261
if ( $this->log( "Easy WP SMTP debug log file\\r\\n\\r\\n" ) === false ) {
262
wp\_die( 'Can\\'t write to log file. Check if plugin directory (' . plugin\_dir\_path( \_\_FILE\_\_ ) . ') is writeable.' );
263
};
264
}
265
$logfile = fopen( plugin\_dir\_path( \_\_FILE\_\_ ) . $log\_file\_name, 'rb' );
266
if ( ! $logfile ) {
267
wp\_die( 'Can\\'t open log file.' );
268
}
252
if ( current\_user\_can( 'manage\_options' ) ) {
253
if ( defined( 'DOING\_AJAX' ) && DOING\_AJAX ) {
254
add\_action( 'wp\_ajax\_swpsmtp\_clear\_log', array( $this, 'clear\_log' ) );
255
add\_action( 'wp\_ajax\_swpsmtp\_self\_destruct', array( $this, 'self\_destruct\_handler' ) );
256
}
257
//view log file
258
if ( isset( $\_GET\[ 'swpsmtp\_action' \] ) ) {
259
if ( $\_GET\[ 'swpsmtp\_action' \] === 'view\_log' ) {
260
$log\_file\_name = $this->opts\[ 'smtp\_settings' \]\[ 'log\_file\_name' \];
261
if ( ! file\_exists( plugin\_dir\_path( \_\_FILE\_\_ ) . $log\_file\_name ) ) {
262
if ( $this->log( "Easy WP SMTP debug log file\\r\\n\\r\\n" ) === false ) {
263
wp\_die( 'Can\\'t write to log file. Check if plugin directory (' . plugin\_dir\_path( \_\_FILE\_\_ ) . ') is writeable.' );
264
};
265
}
266
$logfile = fopen( plugin\_dir\_path( \_\_FILE\_\_ ) . $log\_file\_name, 'rb' );
267
if ( ! $logfile ) {
268
wp\_die( 'Can\\'t open log file.' );
269
}
270
header( 'Content-Type: text/plain' );
271
fpassthru( $logfile );
272
die;
273
}
274
}
275
276
//check if this is export settings request
277
$is\_export\_settings = filter\_input( INPUT\_POST, 'swpsmtp\_export\_settings', FILTER\_SANITIZE\_NUMBER\_INT );
278
if ( $is\_export\_settings ) {
279
$data = array();
280
$opts = get\_option( 'swpsmtp\_options', array() );
281
$data\[ 'swpsmtp\_options' \] = $opts;
282
$swpsmtp\_pass\_encrypted = get\_option( 'swpsmtp\_pass\_encrypted', false );
283
$data\[ 'swpsmtp\_pass\_encrypted' \] = $swpsmtp\_pass\_encrypted;
284
if ( $swpsmtp\_pass\_encrypted ) {
285
$swpsmtp\_enc\_key = get\_option( 'swpsmtp\_enc\_key', false );
286
$data\[ 'swpsmtp\_enc\_key' \] = $swpsmtp\_enc\_key;
287
}
288
$smtp\_test\_mail = get\_option( 'smtp\_test\_mail', array() );
289
$data\[ 'smtp\_test\_mail' \] = $smtp\_test\_mail;
290
$out = array();
291
$out\[ 'data' \] = serialize( $data );
292
$out\[ 'ver' \] = 1;
293
$out\[ 'checksum' \] = md5( $out\[ 'data' \] );
294
295
$filename = 'easy\_wp\_smtp\_settings.txt';
296
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
269
297
header( 'Content-Type: text/plain' );
270
fpassthru( $logfile );
271
die;
272
}
273
}
274
275
//check if this is export settings request
276
$is\_export\_settings = filter\_input( INPUT\_POST, 'swpsmtp\_export\_settings', FILTER\_SANITIZE\_NUMBER\_INT );
277
if ( $is\_export\_settings ) {
278
$data = array();
279
$opts = get\_option( 'swpsmtp\_options', array() );
280
$data\[ 'swpsmtp\_options' \] = $opts;
281
$swpsmtp\_pass\_encrypted = get\_option( 'swpsmtp\_pass\_encrypted', false );
282
$data\[ 'swpsmtp\_pass\_encrypted' \] = $swpsmtp\_pass\_encrypted;
283
if ( $swpsmtp\_pass\_encrypted ) {
284
$swpsmtp\_enc\_key = get\_option( 'swpsmtp\_enc\_key', false );
285
$data\[ 'swpsmtp\_enc\_key' \] = $swpsmtp\_enc\_key;
286
}
287
$smtp\_test\_mail = get\_option( 'smtp\_test\_mail', array() );
288
$data\[ 'smtp\_test\_mail' \] = $smtp\_test\_mail;
289
$out = array();
290
$out\[ 'data' \] = serialize( $data );
291
$out\[ 'ver' \] = 1;
292
$out\[ 'checksum' \] = md5( $out\[ 'data' \] );
293
294
$filename = 'easy\_wp\_smtp\_settings.txt';
295
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
296
header( 'Content-Type: text/plain' );
297
echo serialize( $out );
298
exit;
299
}
300
301
$is\_import\_settings = filter\_input( INPUT\_POST, 'swpsmtp\_import\_settings', FILTER\_SANITIZE\_NUMBER\_INT );
302
if ( $is\_import\_settings ) {
303
$err\_msg = \_\_( 'Error occurred during settings import', 'easy-wp-smtp' );
304
if ( empty( $\_FILES\[ 'swpsmtp\_import\_settings\_file' \] ) ) {
305
echo $err\_msg;
306
wp\_die();
307
}
308
$in\_raw = file\_get\_contents( $\_FILES\[ 'swpsmtp\_import\_settings\_file' \]\[ 'tmp\_name' \] );
309
try {
310
$in = unserialize( $in\_raw );
311
if ( empty( $in\[ 'data' \] ) ) {
298
echo serialize( $out );
299
exit;
300
}
301
302
$is\_import\_settings = filter\_input( INPUT\_POST, 'swpsmtp\_import\_settings', FILTER\_SANITIZE\_NUMBER\_INT );
303
if ( $is\_import\_settings ) {
304
$err\_msg = \_\_( 'Error occurred during settings import', 'easy-wp-smtp' );
305
if ( empty( $\_FILES\[ 'swpsmtp\_import\_settings\_file' \] ) ) {
312
306
echo $err\_msg;
313
307
wp\_die();
314
308
}
315
if ( empty( $in\[ 'checksum' \] ) ) {
309
$in\_raw = file\_get\_contents( $\_FILES\[ 'swpsmtp\_import\_settings\_file' \]\[ 'tmp\_name' \] );
310
try {
311
$in = unserialize( $in\_raw );
312
if ( empty( $in\[ 'data' \] ) ) {
313
echo $err\_msg;
314
wp\_die();
315
}
316
if ( empty( $in\[ 'checksum' \] ) ) {
317
echo $err\_msg;
318
wp\_die();
319
}
320
if ( md5( $in\[ 'data' \] ) !== $in\[ 'checksum' \] ) {
321
echo $err\_msg;
322
wp\_die();
323
}
324
$data = unserialize( $in\[ 'data' \] );
325
update\_option( 'swpsmtp\_options', $data\[ 'swpsmtp\_options' \] );
326
update\_option( 'swpsmtp\_pass\_encrypted', $data\[ 'swpsmtp\_pass\_encrypted' \] );
327
if ( $data\[ 'swpsmtp\_pass\_encrypted' \] ) {
328
update\_option( 'swpsmtp\_enc\_key', $data\[ 'swpsmtp\_enc\_key' \] );
329
}
330
update\_option( 'smtp\_test\_mail', $data\[ 'smtp\_test\_mail' \] );
331
set\_transient( 'easy\_wp\_smtp\_settings\_import\_success', true, 60 \* 60 );
332
$url = admin\_url() . 'options-general.php?page=swpsmtp\_settings';
333
wp\_safe\_redirect( $url );
334
exit;
335
} catch ( Exception $ex ) {
316
336
echo $err\_msg;
317
337
wp\_die();
318
338
}
319
if ( md5( $in\[ 'data' \] ) !== $in\[ 'checksum' \] ) {
320
echo $err\_msg;
321
wp\_die();
322
}
323
$data = unserialize( $in\[ 'data' \] );
324
foreach ( $data as $key => $value ) {
325
update\_option( $key, $value );
326
}
327
set\_transient( 'easy\_wp\_smtp\_settings\_import\_success', true, 60 \* 60 );
328
$url = admin\_url() . 'options-general.php?page=swpsmtp\_settings';
329
wp\_safe\_redirect( $url );
330
exit;
331
} catch ( Exception $ex ) {
332
echo $err\_msg;
333
wp\_die();
334
339
}
335
340
}
easy-wp-smtp/trunk/readme.txt
r2052057
r2052058
6
6
Tested up to: 5.1
7
7
Requires PHP: 5.3
8
Stable tag: 1.3.9
8
Stable tag: 1.3.9.1
9
9
License: GPLv2 or later
10
10
License URI: http://www.gnu.org/licenses/gpl-2.0.html
…
…
80
80
== Changelog ==
81
81
82
= 1.3.9.1 =
83
* Fixed potential vulnerability in import\export settings.
84
82
85
= 1.3.9 =
83
86
* Added Export\Import settings functionality.
…
…
85
88
86
89
= 1.3.8.1 =
87
* Fixed incompatability with WP versions older than 4.7.0 (thanks to stevendigital for reporting).
90
* Fixed incompatibility with WP versions older than 4.7.0 (thanks to stevendigital for reporting).
88
91
89
92
= 1.3.8 =