lesterchan / wp-postratings

Adds an AJAX rating system for your WordPress blog's post/page.
https://wordpress.org/plugins/wp-postratings/
122 stars 82 forks source link

Improper generation of admin-ajax.php URL if FORCE_SSL_LOGIN is on #75

Open janrenn opened 8 years ago

janrenn commented 8 years ago

Consider WP configuration where admin is under HTTPS and frontend still on HTTP protocol (FORCE_SSL_ADMIN is on). wp-postratings.php then generates ajax_url using admin_url() without protocol check.

If one uses self-signed certificate (acceptable for admin login purposes), Postratings will not work - the AJAX POST request on admin-ajax.php by WP-Postratings will be blocked (visitor does not have the certificate among security exceptions). The line 169 of wp-postratings.php should better read:

'ajax_url' => admin_url('admin-ajax.php', ( is_ssl() ? 'https' : 'http' )),

lesterchan commented 8 years ago

That was the original code, the reason why I changed it is https://github.com/lesterchan/wp-polls/pull/19 and it makes sense, so unlikely I will change this.

Also with Let's Encrypt, you can use a proper free SSL cert rather than a self-signed one.

janrenn commented 8 years ago

Yes, you are right. There can be a dispute if it is more rare to use self-signed certificate for WP admin login or to augment FORCE_SSL_ADMIN with mod_rewrite what was the reason to change in lesterchan/wp-polls#19.

Notice that not null, but "admin" is default scheme, if you do not use second parameter in admin_url(), then set_url_scheme() tests is_ssl() || force_ssl_admin(). It thinks we are in Admin. But we are not, we're on public page. Should the plugin respect rather fact we call a component from admin folder or rather actual context? I really do not expect that any plugin will call HTTPS if only FORCE_SSL_ADMIN is on.

Anyway, it is disputed, the main issue here is WP architecture which uses admin folder calls for AJAX components from front-end, it should be separated. For those, who face issues with HTTPS calls from HTTP page as me: use admin_url filter to choose the intended plugin behavior, e.g.

// somewhere in functions.php
function repair_postratings_admin_ajax( $url, $path ) {
    if ( $path == 'admin-ajax.php' && is_ssl() == FALSE ) {
        return str_replace( 'https:', 'http:', $url );
    }
    return $url;
}
add_filter( 'admin_url', 'repair_postratings_admin_ajax', 20, 2 );

Thank you.