Back-End

25 mar, 2015

Prevenção de ataques via bot em WordPress usando noCaptcha e reCaptcha

Publicidade

Há muitas soluções diferentes para evitar que bots enviem formulários web; uma das soluções mais populares é o reCaptcha, que mostra uma imagem contendo algum texto que o usuário tem que digitar para enviar o formulário com sucesso. Era difícil para bots lerem o texto na imagem, mas à medida que os algoritmos dos robôs se tornaram mais avançados, eles logo começaram a quebrar essa segurança. Não era mais um método seguro. Esse método antigo é ruim em termos de facilidade de uso. Então, o Google criou uma nova tecnologia de reCaptcha chamada No Captcha reCaptcha.

Neste artigo, vamos entender como funciona exatamente o No Captcha reCaptcha e como criar um plugin que o integra ao WordPress, de forma a proteger o registro de usuários e formulários de comentários prevenindo vários tipos de ataques.

hero-recaptcha-demo

Um olhar para o No Captcha reCaptcha

O No Captcha reCaptcha apenas exibe uma caixa pedindo ao usuário para verificar se ele não é um bot. Pode parecer muito simples, mas, internamente, o Google usa algoritmos e métodos avançados para saber se o usuário é um bot ou não. Esse novo modelo é mais amigável e seguro do que o antigo.

Como é que isso funciona?

Pode parecer uma caixa de seleção simples, mas não se trata apenas de uma caixa de seleção. Seu método inclui uma interface gráfica que se comporta como uma caixa de seleção. A maioria dos bots não executa JavaScript, então não pode imitá-lo. Mas, para os bots que podem emular campos em formulários, isso é rastreado por movimentos do mouse e pelos algoritmos do Adsense contra fraudes, utilizando o método de detecção de cliques do Google.

Registrando um aplicativo No Captcha reCaptcha

Os usuários que instalarem este plugin precisam registrar seu website para obter a chave do site e uma chave secreta.

Você precisa criar uma página de configurações para o plugin que permite que o administrador do WordPress possa instalar a chave secreta do site que foi recuperada no painel de administração reCaptcha.

function 
no_captcha_recaptcha_menu()
{
    add_menu_page( "reCapatcha Options", "reCaptcha Options", "manage_options", "recaptcha-options", "recaptcha_options_page", "", 100 );
}

function recaptcha_options_page()
{
    ?>
        <div class="wrap">
        <h1>reCaptcha Options</h1>
        <form method="post" action="options.php">
            <?php
                settings_fields( "header_section" );
                do_settings_sections( "recaptcha-options" );
                submit_button();                     
            ?>          
        </form>
    </div>
    <?php
}

add_action( "admin_menu", "no_captcha_recaptcha_menu" );

function display_recaptcha_options()
{
    add_settings_section( "header_section", "Keys", "display_recaptcha_content", "recaptcha-options" );

    add_settings_field( "captcha_site_key", __("Site Key"), "display_captcha_site_key_element", "recaptcha-options", "header_section" );
    add_settings_field( "captcha_secret_key", __("Secret Key"), "display_captcha_secret_key_element", "recaptcha-options", "header_section" );

    register_setting( "header_section", "captcha_site_key" );
    register_setting( "header_section", "captcha_secret_key" );
}

function display_recaptcha_content()
{
    echo __( '<p>You need to <a href="https://www.google.com/recaptcha/admin" rel="external">register you domain</a> and get keys to make this plugin work.</p>' );
    echo __( "Enter the key details below" );
}
function display_captcha_site_key_element()
{
    ?>
        <input type="text" name="captcha_site_key" id="captcha_site_key" value="<?php echo get_option('captcha_site_key'); ?>" />
    <?php
}
function display_captcha_secret_key_element()
{
    ?>
        <input type="text" name="captcha_secret_key" id="captcha_secret_key" value="<?php echo get_option('captcha_secret_key'); ?>" />
    <?php
}

add_action( "admin_init", "display_recaptcha_options" );

Vamos ver como o código acima funciona:

  • Criamos uma página de configurações no painel de administração do WordPress.
  • EsSa página exibe as configurações de dois campos de texto de entrada para informar a chave do site e uma chave secreta.
  • EsSas chaves são armazenadas como opções do WordPress. Chamamos as opções de site_key e secret_key.

Prevenindo spams em comentários

comments

É preciso integrar o reCaptcha nos formulários de comentários para evitar bots que enviam spam nos comentários.

Crie um arquivo style.css em sua pasta de plugins e coloque este código:

#submit { display: none; }

O código acima esconde o botão de envio do formulário no comentário do WordPress para que possamos colocar o box reCaptcha acima do botão de envio do formulário.

Aqui está o código para integrar o reCaptcha em formulários de comentários:

add_action( "wp_enqueue_scripts", "frontend_recaptcha_script" );

function frontend_recaptcha_script()
{
    if( get_option( 'captcha_site_key' ) && get_option( 'captcha_secret_key' ) )
    {
        wp_register_script( "recaptcha", "https://www.google.com/recaptcha/api.js" );
        wp_enqueue_script( "recaptcha" );

        $plugin_url = plugin_dir_url( __FILE__ );

        wp_enqueue_style( "no-captcha-recaptcha", $plugin_url . "style.css" );
    }   
}

add_action( "comment_form", "display_comment_recaptcha" );

function display_comment_recaptcha()
{
    if( get_option( 'captcha_site_key' ) && get_option( 'captcha_secret_key' ) )
    {
        ?>
            <div class="g-recaptcha" data-sitekey="<?php echo get_option( 'captcha_site_key' ); ?>"></div>
            <input name="submit" type="submit" value="Submit Comment">
        <?php   
    }

}

add_filter( "preprocess_comment", "verify_comment_captcha" );

function verify_comment_captcha( $commentdata )
{
    if( isset( $_POST['g-recaptcha-response'] ) )
    {
        $recaptcha_secret = get_option( 'captcha_secret_key' );
        $response = file_get_contents( "https://www.google.com/recaptcha/api/siteverify?secret=" . $recaptcha_secret . "&response=" .$_POST['g-recaptcha-response'] );
        $response = json_decode( $response, true );
        if( true == $response["success"] )
        {
            return $commentdata;
        }
        else
        {
            echo __( "Bots are not allowed to submit comments." );
            return null;
        }
    }
    else
    {
        if( get_option( 'captcha_site_key' ) && get_option( 'captcha_secret_key' ) )
        {
            echo __( "Bots are not allowed to submit comments. If you are not a bot then please enable JavaScript in browser." );
            return null;    
        }   
        else
        {
            return $commentdata;
        }
    }
}

Vamos ver como o código acima funciona:

  • Nós enfileiramos o JavaScript do reCaptcha do Google no frontend do WordPress usando a ação wp_enqueue_scripts.
  • Também enfileiramos o style.css utilizando o wp_enqueue_style.
  • Dentro do formulário de comentários, exibiremos a caixa de seleção usando a ação comment_form.
  • Quando o comentário é digitado e antes de inseri-lo no banco de dados, o WordPress chama o filtro preprocess_comment. Dentro do filtro, vamos verificar se o usuário é humano ou bot. Se for humano, retornamos o comentário a ser inserido; caso contrário, retornamos nulo para evitar que o comentário seja adicionado ao banco de dados.

Prevenindo ataques de força bruta

login

Precisamos integrar o reCaptcha no formulário de login da administração do WordPress para evitar bots que executam ataques de força bruta para quebrar senhas. Aqui está o código para integrá-lo no formulário de login da área administrativa:

add_action( "login_enqueue_scripts", "login_recaptcha_script" );

function login_recaptcha_script()
{
    if( get_option( 'captcha_site_key' ) && get_option( 'captcha_secret_key' ) )
    {
        wp_register_script( "recaptcha_login", "https://www.google.com/recaptcha/api.js" );
        wp_enqueue_script( "recaptcha_login" );
    }
}

add_action( "login_form", "display_login_captcha" );

function display_login_captcha()
{
    if( get_option( 'captcha_site_key' ) && get_option( 'captcha_secret_key' ) )
    {
        ?>
            <div class="g-recaptcha" data-sitekey="<?php echo get_option('captcha_site_key' ); ?>"></div>
        <?php
    }   
}

add_filter( "wp_authenticate_user", "verify_login_captcha", 10, 2 );

function verify_login_captcha( $user, $password )
{
    if( isset( $_POST['g-recaptcha-response'] ) )
    {
        $recaptcha_secret = get_option( 'captcha_secret_key' );
        $response = file_get_contents( "https://www.google.com/recaptcha/api/siteverify?secret=" . $recaptcha_secret . "&response=" . $_POST['g-recaptcha-response'] );
        $response = json_decode( $response, true );
        if( true == $response["success"] )
        {
            return $user;
        }
        else
        {
            return new WP_Error( "Captcha Invalid", __( "<strong>ERROR</strong>: You are a bot" ) );
        } 
    }
    else
    {
        if( get_option( 'captcha_site_key' ) && get_option( 'captcha_secret_key' ) )
        {
            return new WP_Error( "Captcha Invalid", __( "<strong>ERROR</strong>: You are a bot. If not then enable JavaScript" ) );
        }
        else
        {
            return $user;
        }
    }   
}

Vamos ver como o código acima funciona:

  • Nós enfileiramos o JavaScript do Google reCaptcha para WordPress usando a ação login_enqueue_scripts.
  • Vamos exibir a caixa de seleção usando a ação register_form.
  • Antes de produzir o resultado final de autenticação, o WordPress executa o filtro wp_authenticate_user para nos permitir adicionar uma etapa de validação extra.Vamos verificar se o usuário é bot ou humano dentro desse filtro. Se for humano, retornamos o objeto usuário. Se não for, retornamos um objeto vazio e uma mensagem de erro será exibida.

Prevenindo a criação de contas falsas

register

Precisamos integrar o reCaptcha no formulário de registro do admin para evitar que bots criem contas falsas. Aqui está o código para isso:

add_action( "register_form", "display_register_captcha" );

function display_register_captcha()
{
    if( get_option( 'captcha_site_key' ) && get_option( 'captcha_secret_key' ) )
    {
        ?>
            <div class="g-recaptcha" data-sitekey="<?php echo get_option( 'captcha_site_key' ); ?>"></div>
        <?php   
    }       
}

add_filter( "registration_errors", "verify_registration_captcha", 10, 3 );

function verify_registration_captcha( $errors, $sanitized_user_login, $user_email )
{
    if( isset( $_POST['g-recaptcha-response'] ) )
    {
        $recaptcha_secret = get_option( 'captcha_secret_key' );
        $response = file_get_contents( "https://www.google.com/recaptcha/api/siteverify?secret=" . $recaptcha_secret . "&response=" . $_POST['g-recaptcha-response'] );
        $response = json_decode( $response, true );
        if( true == $response["success"] )
        {
            return $errors;
        }
        else
        {
            $errors->add( "Captcha Invalid", __( "<strong>ERROR</strong>: You are a bot" ) );
        }
    }
    else
    {   
        if( get_option( 'captcha_site_key' ) && get_option( 'captcha_secret_key' ) )
        {
            $errors->add( "Captcha Invalid", __( "<strong>ERROR</strong>: You are a bot. If not then enable JavaScript" ) );
        }
        else
        {
            return $errors;
        }

    }   

    return $errors;
}

Vamos ver como o código acima funciona:

  • Nós exibimos a caixa de seleção usando a ação register_form.
  • Antes de produzir o resultado final de autenticação, o WordPress executa o filtro registration_errors para nos permitir adicionar uma etapa de validação extra.Vamos verificar se o usuário é bot ou humano dentro desse filtro. Se for humano, retornamos objeto de erro vazio. Se não, adicionamos um add ao objeto de erro e o retornamos.

Evitando que robôs tentem utilizar o formulário de senha perdida

lost_password

Precisamos integrar o reCaptcha também no formulário de recuperação da senha do administrador para evitar bots que tentam recuperá-la através desse formulário. Aqui está o código para integrá-lo ao formulário administrativo de recuperação da senha:

add_action( "lostpassword_form", "display_login_captcha" );
add_action( "lostpassword_post", "verify_lostpassword_captcha" );

function verify_lostpassword_captcha()
{
    if( isset( $_POST['g-recaptcha-response'] ) )
    {
        $recaptcha_secret = get_option( 'captcha_secret_key' );
        $response = file_get_contents( "https://www.google.com/recaptcha/api/siteverify?secret=" . $recaptcha_secret . "&response=" . $_POST['g-recaptcha-response'] );
        $response = json_decode( $response, true );
        if( true == $response["success"] )
        {
            return;
        }
        else
        {
            wp_die( __( "<strong>ERROR</strong>: You are a bot" ) );
        }
    }
    else
    {
        if( get_option( 'captcha_site_key' ) && get_option( 'captcha_secret_key' ) )
        {
            wp_die( __( "<strong>ERROR</strong>: You are a bot. If not then enable JavaScript" ) ); 
        }
        else
        {
            return;
        }

    }   

    return $errors; 
}

Vamos ver como o código acima funciona:

  • Nós exibimos a caixa de seleção usando a ação lostpassword_form.
  • Antes de produzir o passo final da redefinição de senha do WordPress, execute a ação lostpassword_post para adicionar uma etapa de validação extra.Vamos verificar se o usuário é um bot ou humano dentro desse filtro. Se for humano, não retornamos mais nada; se não for, terminamos o script com uma mensagem de erro.

Considerações finais

Esta é uma nova maneira de proteger seus formulários de sites WordPress contra bots e aumentar a facilidade de utilização. Você também pode aprender como o Google detecta um bot ou um humano usando esse novo tipo de captcha.

 

***

Narayan Prusty faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://davidwalsh.name/preventing-bot-attacks-wordpress-captcha-recaptcha