WP Live Chat Support Plugin Vulnerability – Update Now!

Published by John on May 17, 2019 Under Wordpress

If you are using the WP Live Chat Support WordPress plugin, you need to disable or update it asap! Anything older than version 8.0.29 is vulnerable to a bug that allows an unauthenticated user to insert JavaScript to front end pages of the WordPress website. This is actively being exploited as of 05/17/2019.

The plugin includes an option for Custom Javascript, which is located in the settings: Live Chat -> Settings -> Custom Scripts -> Custom JS

* If your site has been hacked as a result of this vulnerability, along with your other WordPress Hack Cleanup steps, like checking for malicious uploaded files, new users, etc, verify the above setting is empty(or at least does not have any malicious code in it)!

When present, this gets added to the header of each front-end page wrapped in a <script> element.

There was some sloppy code that allowed this to be edited, I believe without even being logged into the site. Since anything added there will be printed on the front end of the website as JavaScript, the hack was being used to redirect users to a spam site.

In the support forum, the plugin developers indicated it was added when an admin clicked a malicious link, however I do not think that was the case.

The function that saves the setting was added to the admin_init hook and there was nothing in place to check if the user was logged in or it was a valid request. It also just checks for whether two $_POST values are present, ‘wplc_custom_js’ being the malicious one, and if so, updates blindly.

Per WordPress’s support page, admin_init runs on /wp-admin/admin-ajax.php, which is used by some plugins/themes, including WP Live Chat Support, even when the user is not a logged in admin. So, most likely you could exploit this by a valid request to /wp-admin/admin-ajax.php and adding ‘wplc_custom_js’ as a POST value.

Their update includes adding a check to make sure the user is logged in before updating, as well as adding a NONCE to other updates. However, they probably need to rework their save process.

The Sloppy Function, which adds a hook to ‘wplc_hook_head’

add_action( "wplc_hook_head", "wplc_custom_scripts_save" );
 * Saves the custom scripts into the options table
 * @return void
function wplc_custom_scripts_save(){

        if( isset( $_POST['wplc_save_settings'] ) ){

                if( isset( $_POST['wplc_custom_css'] ) ){
                        update_option( "WPLC_CUSTOM_CSS", nl2br( $_POST['wplc_custom_css'] ) );

                if( isset( $_POST['wplc_custom_js'] ) ){
                        update_option( "WPLC_CUSTOM_JS", nl2br( $_POST['wplc_custom_js'] ) );



The hook ‘wplc_hook_head’ gets fired in function ‘wplc_head_basic’ :

function wplc_head_basic() {
    global $wpdb;


    if (isset($_POST['wplc_save_settings'])) {


And ‘wplc_head_basic’ is added to ‘admin_init’ :

if (function_exists('wplc_head_pro')) {
    add_action('admin_init', 'wplc_head_pro');
} else {
    add_action('admin_init', 'wplc_head_basic');

And then on the front end of the website, it gets added to the ‘wp_head’ action:

add_action( "wp_head", "wplc_custom_scripts_frontend" );
 * Display the custom scripts on the front end of the site
 * @return string
function wplc_custom_scripts_frontend(){

        $wplc_custom_css = get_option( "WPLC_CUSTOM_CSS" );
        $wplc_custom_js = get_option( "WPLC_CUSTOM_JS" );

        if( $wplc_custom_css ){
                echo "<!-- WPLC Custom CSS -->";
                echo "<style>";
                echo strip_tags( stripslashes( $wplc_custom_css ) );
                echo "</style>";

        if( $wplc_custom_js ){
                echo "<!-- WPLC Custom JS -->";
                echo "<script>";
                echo strip_tags( stripslashes( $wplc_custom_js ) );
                echo "</script>";


No Comments |

Add a Comment