it-swarm-pt.tech

WP Admin AJAX Segurança - usando POST para incluir um URL relativo

Eu configurei vários scripts WordPress Admin AJAX (que são executados apenas no painel Admin) que atualmente usam separado actions, functions e nonces.

A única diferença "real" entre esses scripts é a função PHP. Então, em um esforço para simplificar o sistema, escrevi 1 função JS e 1 função principal PHP para lidar com todas elas.

Um valor $ _POST é enviado com um caminho para a inclusão. Portanto, quando wp_ajax_custom_func() executa o PHP arquivo é incluído e envolvido em locate_template()

Funciona muito bem, mas estou preocupado se isso cria uma falha de segurança?

Estou ciente de que os atacantes podem tentar um falso nonce, enviar dados falsificados POST para admin-ajax.php, ataques XSS/cross-scripting, ect ...

Estou assumindo que, porque envolvi o include em locate_template(), isso ajudará a proteger o sistema. (lado longo um SSL, wp_verify_nonce e current_user_can é claro)

Aqui está o conceito central, simplificado.

Configuração

 wp_enqueue_script( 'ajax_js_class', 
         get_template_directory_uri() . '/theme/ajax_js_class.js' 
     );

 wp_localize_script( 'ajax_js_class', 'custom_settings', array(
        'my_ajaxurl'    => admin_url( 'admin-ajax.php' )
         // nonce and action are attached at the form level
    ) );

Função

  add_action( 'wp_ajax_run_ajax_class_func', 'run_ajax_class_func' ); 
  // wp_ajax_nopriv_run_ajax_class_func is not used

function run_ajax_class_func() {
    if(isset($_POST['nonce'])) {
        $nonce=  $_POST['nonce']; // the nonce from the form
        $action = $_POST['action_hash']."-special-string"; // changes on each form
        $verify_nonce = wp_verify_nonce($nonce, $action); 

        if( $verify_nonce !== false ) {
            if(isset($_POST['path']) && current_user_can('administrator') ) {
                $path = $_POST['path']; // <= this is my concern...
                include locate_template($_POST['path']);
            } else {
            $output = json_encode( array( "success" => "false", "message" => "fail") );
            }
        } else {
        $output = json_encode( array( "success" => "false", "message" => "fail") );
        }
    } else {
      $output = json_encode( array( "success" => "false", "message" => "fail") );
    }

    echo $output; // this is handled in the include above
    // always die
    die();
}

HTML Essentials

 <?php $nonce = wp_create_nonce( $random_hash."-special-string" ); ?>
 <form>
    <input type="hidden" name="path" value="in/theme/run_this.php" >
    <input type="hidden" name="nonce" value="<?php echo $nonce; ?>" >
    <input type="hidden" name="action_hash" value="<?php echo $random_hash; ?>" >

Js Essentials Localizados

 $.post(custom_settings.my_ajaxurl, data, function(response) {

Eu tentei atacar o formulário (usando o Fiddler2 para modificar os cabeçalhos e postar dados), mas suspeito que sofro de viés de confirmação.

Eu gostaria de consultar a comunidade para ver se essa ideia é ruim ou boa. (más ideias merecem críticas)

Perguntas:

  1. Se eu tiver protegido a função wp_ajax (de acordo com as práticas recomendadas do WordPress), é OK usar POST data para incluir um arquivo dentro do WP Admin AJAX açao?
  2. Estou tornando mais fácil para os invasores abusarem do sistema?
  3. Isso está criando uma porta traseira desnecessária no sistema apenas para evitar escrever várias funções adicionais, ou seja: é preguiçoso?

No fechamento, se criar cada nicho, enfileirar, forma e ação como scripts completamente separados é mais seguro por favor elabore por que.

Referência e pesquisa:

1
Christian Žagarskas

Se você usar niveis corretamente, não será possível fazer o site processar pedidos falsos ... Então essa parte deve ser segura, mas ... Ainda há uma falha de segurança na sua abordagem ...

E se eu puder fazer você executar meu script JS em seu navegador, enquanto estiver logado como administrador? É possível.

Desta forma, o nonce não causará erro de validação e seu código executará o que eu quiser - porque você não verifica a entrada do usuário ...

Portanto, toda a sua segurança é baseada na possibilidade de injetar algum JS em seu site - e isso é muito comum - basta dar uma olhada no histórico de malware no WP ...

Seria muito mais seguro se o modelo fosse carregado com base em dados verificados. Portanto, não o carregue diretamente, mas faça uma lista de modelos corretos e seguros e carregue-os com base na variável enviada no POST.

Então, de volta para suas 3 perguntas:

1. Se eu tiver assegurado a função wp_ajax (de acordo com as boas práticas do WordPress), não há problema em usar dados POST para incluir um arquivo dentro do WP Admin AJAX açao?

Não. Não há problema em carregar nenhum arquivo com base no caminho enviado pelo usuário. É muito mais seguro se você passar uma variável e depois traduzir essa variável para o caminho de um arquivo no PHP.

2. Estou tornando mais fácil para os invasores abusarem do sistema?

Você não está facilitando muito, mas sim - será possível atacar esse código.

3. Isso está criando uma porta traseira desnecessária no sistema apenas para evitar escrever várias funções adicionais, ou seja: é preguiçoso?

Sim. Mas você não precisa escrever várias funções. Você só tem que proteger este corretamente e lembre-se - você nunca deve confiar em nada que vem do usuário.

1
Krzysiek Dróżdż