The Blog

Visual Composer/WP Bakery Masonry Grid & Admin SSL

I’m running a site that uses Visual Compower/WP Bakery. On one of the pages, I installed the Post Masonry Grid to display my posts.

Problem

When I initially loaded the page, all I got was a blank screen. I remembered dealing with a problem like this before when running my wordpress site administration over SSL only. I enforce SSL on WordPress admins sometimes using the following line of code in the wp-config.php file:

// force the site admin to run over ssl
define('FORCE_SSL_ADMIN', true);

So, I switched my page, the page running the grid, to HTTPS and the grid loaded just fine. Likewise, if I turn of admin SSL, and then run the page over regular HTTP, the grid will also load.

Admin-ajax.php

So, I checked my developer console in the browser, specifically the networking tab, to see what kind of ajax request was being made back to wordpress. The requested URL was https://mydomain.com/wp-admin/admin-ajax.php. POST was the type of request being made along with the following POST body:

action=vc_get_vc_grid_data
vc_action=vc_get_vc_grid_data
tag=vc_masonry_grid
data[visible_pages]=5
data[page_id]=1464
data[style]=all-masonry
data[action]=vc_get_vc_grid_data
data[shortcode_id]=1521226458000-6f3d3fad-90a7-7
data[tag]=vc_masonry_grid
vc_post_id=1464
_vcnonce=d5199aa52a

You can see there’s a data[action] variable defined here. When passed to the admin-ajax.php file, that is combined with “wp_ajax_nopriv” and then passed to the “do_action” function. The following code shows the end of the admin-ajax.php file and the location of the do_action function in question. It’s passed the “wp_ajax_nopriv_vc_get_vc_grid_data” key.

if ( is_user_logged_in() ) {
	...
	do_action( 'wp_ajax_' . $_REQUEST['action'] );
} else {
	// If no action is registered, return a Bad Request response.
	if ( ! has_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] ) ) {
		wp_die( '0', 400 );
	}

	/**
	 * Fires non-authenticated Ajax actions for logged-out users.
	 *
	 * The dynamic portion of the hook name, `$_REQUEST['action']`,
	 * refers to the name of the Ajax action callback being fired.
	 *
	 * @since 2.8.0
	 */
	do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] );
}

Next, I needed to find out where the “vc_get_vc_grid_data” key was being called from within the Visual Composer code. So, I went to the server terminal and used grep to search the code:

root [/home/to/my/site] grep -r "vc_get_vc_grid_data"

./include/classes/shortcodes/vc-basic-grid.php:                 'action' => 'vc_get_vc_grid_data',
./include/autoload/hook-vc-grid.php:            add_action( 'wp_ajax_vc_get_vc_grid_data', array(
./include/autoload/hook-vc-grid.php:            add_action( 'wp_ajax_nopriv_vc_get_vc_grid_data', array(

After digging through those files, I realized Visual Composer was calling the vc_verify_public_nonce function. So, I did another grep search:

root [/home/to/my/site] grep -r "vc_verify_public_nonce"

./include/classes/core/access/abstract-class-vc-access.php: return $this->check( 'vc_verify_public_nonce'...
./include/autoload/hook-vc-grid.php: $allowed = apply_filters( 'vc_grid_get_grid_data_access', vc_verify_public_nonce ...
./include/helpers/helpers_factory.php: function vc_verify_public_nonce( $nonce = '' ) {...

I found the main codeI was looking for in /include/helpers/helpers_factory.php within the Visual Composer plugin. As of this post, the following code sits around line #500 (I added a few var_dumps for debugging):

/**
 * @param $nonce
 * @param $data
 *
 * @return bool
 */
function vc_verify_nonce( $nonce, $data ) {
	// var_dump(wp_nonce_field('vc-nonce-vc-public-nonce'));
	// var_dump($nonce, $data, wp_verify_nonce($nonce, 'vc-nonce-vc-public-nonce')); exit;
	return (bool) wp_verify_nonce( $nonce, ( is_array( $data ) ? ( 'vc-nonce-' . implode( '|', $data ) ) : ( 'vc-nonce-' . $data ) ) );
}

By doing some browser output with this file, I was able to verify that the nonce changes values when HTTP and HTTPS are mixed together. This caused the whole thing to fail silently, omitting the grid results.

Solution

So, as of right now, I know of two ways to fix this. 1. Run the entire site over SSL. 2. Install this line of code in the theme functions.php file:

// disable nonce validation on ajax requests
add_filter('vc_grid_get_grid_data_access','__return_true');

Spread the love

No comments yet.

Leave a Comment

Remember to play nicely folks, nobody likes a troll.

You must be logged in to post a comment.