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:
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:
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:
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.
Você não está facilitando muito, mas sim - será possível atacar esse código.
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.