Not Really a WordPress Plugin Vulnerability – Week of October 13, 2017
In reviewing reports of vulnerabilities in WordPress plugins we often find that there are reports for things that don’t appear to be vulnerabilities. For more problematic reports we have been releasing posts detailing why the vulnerability reports are false, but there have been a lot of that we haven’t felt rose to that level. In particular are items that are not outright false, just the issue is probably more accurately described as a bug. We have been thinking that providing information on why those are not included in our service’s data could be useful, so we are trying out putting a weekly post when that occurs detailing those issues.
Directory Traversal Vulnerability in WP Smush
There recently was a report of a directory traversal vulnerability in WP Smush. If you believed the developers (who are also the developer of a security plugin) this is a vulnerability, the changelog for version 2.7.6 is:
- Security: Fixed path traversal vulnerability. Thanks Ricardo Sánchez(@neorichi) for responsible disclosure.
The report provides a link that is supposed to confirm that it is a vulnerability, that link is to this comment in a thread on the WordPress Support Forum:
@neorichi, Just to update you, we’ve a new security release to fix the bug.
Appreciate your efforts to report this responsibly.
Cheers, Umesh
Looking at the proof of concept it seemed like something might be off about this, as it seemed that you might need a nonce to exploit the issue, but the report doesn’t explain whether a valid nonce is needed or not and if so, where it could be found:
http://localhost/wordpress/wp-admin/admin-ajax.php?dir=../../../../../../&multiSelect=true&action=smush_get_directory_list&list_nonce=xxxxxxx
That URL indicates that an AJAX accessible function is being accessed. Looking at version 2.7.5 that function is only accessible to those logged in, which is not noted in the report (that would make this an authenticated vulnerability at least):
43 | add_action( 'wp_ajax_smush_get_directory_list', array( $this, 'directory_list' ) ); |
Looking the function being accessed, directory_list(), which is located in the file /lib/class-wp-smush-dir.php, you can see that before it checks for a valid nonce it checks to make sure the user making the request has the “manage_options” capability:
341 342 343 344 345 346 347 | function directory_list() { //Check For Permission if ( ! current_user_can( 'manage_options' ) || ! is_user_logged_in() ) { wp_send_json_error( "Unauthorized" ); } //Verify nonce check_ajax_referer( 'smush_get_dir_list', 'list_nonce' ); |
Users with the “manage_options” capability would normally only be Administrators (and if others are given the capability they would normally be able to create Administrators accounts), which would normally have the ability to view the directory structure with their capabilities, so this isn’t really a vulnerability.
If you are going to claim this is a vulnerability (as the folks at ThreatPress, WPCampus, and the WPScan Vulnerability Database have) we don’t see how it could be claimed that it is fixed as the change just restricts you to accessing directories within in the WordPress directory:
349 350 351 352 353 354 355 356 357 358 359 | //Get the Root path for a main site or subsite $root = realpath( $this->get_root_path() ); $dir = isset( $_GET['dir'] ) ? ltrim( $_GET['dir'], '/' ) : null; $postDir = strlen( $dir ) > 1 ? path_join( $root, $dir ) : $root . $dir; $postDir = realpath( rawurldecode( $postDir ) ); //If the final path doesn't contains the root path, bail out. if ( !$root || $postDir === false || strpos( $postDir, $root ) !== 0 ) { wp_send_json_error( "Unauthorized" ); } |
Persistent Cross-Site Scripting (XSS) Vulnerability in Contact Widgets
A frequent source of false claims of vulnerabilities in WordPress plugins is a lack of understanding of the WordPress security model. WordPress has a capability “unfiltered_html” that allows users to do the equivalent of cross-site scripting (XSS), which in simply terms is just the ability to use JavaScript code. A claim of a persistent cross-site scripting (XSS) vulnerability in the plugin Contact Widgets involved adding JavaScript code to a widget that is part of the plugin. Normally only Administrators are allowed to edit widgets, so the testing likely was done with a user who has the ability to do the equivalent of the vulnerability.
In one of the responses to the claim, one of the developers responded:
Then this is not a bug. We explicitly allow Administrators to do whatever they want in the widget via that
unfiltered_html
permission, just as core does with the Text widget.
Looking at the code here is what he is talking about (in the file /includes/class-contact.php):
201 | 'sanitizer' => function( $value ) { return current_user_can( 'unfiltered_html' ) ? $value : wp_kses_post( stripslashes( $value ) ); }, |
Just to further confirm things were working correctly, we gave an Author level user, who doesn’t have the “unfiltered_html” capability, the ability to edit widgets by giving them the “edit_theme_options” and then tried the proof of concept. As expected the malicious input was sanitized and there was not exploitation, so there isn’t a vulnerability here at all.