web-dev-qa-db-fra.com

WordPress Ajax Data Security

Je suis conscient que les nonces ne doivent pas vérifier les intentions, mais cela n’a aucun sens si je peux les utiliser pour limiter les lectures de bases de données? Je veux dire, je vais chercher les enregistrements de la base de données en utilisant AJAX, mais je ne veux pas que quiconque ait ces données par d'autres moyens (demandes POST adressées à cette page admin-ajax.php).

Par exemple, dans mon gestionnaire AJAX, j'ai beaucoup de travail (j'envoie $myid avec l'action dans l'appel AJAX:):

$myid = 5575;
$query = "SELECT `id` FROM table WHERE `user_id` = $myid;";
$data = $wpdb->get_col( $query );
echo json_encode($data);
die();

J'appelle autant de données via AJAX, comment puis-je le protéger contre les utilisateurs pervers qui peuvent essayer d'appeler directement POST à cette page?

Edit: @Bainternet Merci pour l'explication détaillée, je l'apprécie, mais ma question porte vraiment sur ce que @Milo a dit et je peux voir que si je ne peux pas créer un nonce unique pour cette demande, je ne peux rien faire @goldenapples. Droite?

Je gère tout ça avec Facebook JS SDK, donc tout ce qui doit être fait est avec AJAX seulement (sans chargement de page), et tout ce que je peux penser de faire en sorte que l'utilisateur se connecte à wp_signon() ou quoi que ce soit, n'importe qui le reste peut le faire aussi sans autorité. Donc, je ne trouve pas unique chez un utilisateur qui utilise réellement le site et celui qui essaie de lire des données autres que le site appelle à récupérer les données. Et tout ce que je peux faire pour le connecter ou quoi que ce soit, peut aussi être répliqué par quelqu'un d'autre. Quelqu'un peut-il penser à quelque chose?

Mise à jour: Je pense avoir trouvé une solution de contournement en l'appelant simplement avec action et obtenir d'autres paramètres de Facebook à l'aide de PHP SDK. Mais je suis toujours ouvert aux suggestions ou à toute autre chose à ce sujet.

6
Ashfame

Il y a quelques choses que vous pouvez faire pour rendre plus sûr:

Tout d’abord, l’appel Ajax lui-même devrait se faire avec un nonce WordPress comme vous l’avez dit:

<script type="text/javascript" >
    jQuery(document).ready(function($) {
        var data = {
            action: 'ACTION_NAME',
            Whatever_data: 1234,
            _ajax_nonce: <?php echo wp_create_nonce( 'my_ajax_nonce' ); ?>
        };
        $.post(ajaxurl, data, function(response) {
            alert('Got this from the server: ' + response);
        });
    });
</script>

Dans le code ci-dessus, gardez à l'esprit les deux attributs action et _ajax_nonce qui sont nécessaires pour vérifier l'appel à admin-ajax.php. Dans les premières lignes de code, vérifiez si une action a été envoyée au serveur et, dans le cas contraire, die()'s ( FIRST CHECK ) puis en utilisant cette action, vous appelez votre propre fonction ajax avec un crochet d’action:

//if you want only logged in users to access this function use this hook
add_action('wp_ajax_ACTION_NAME', 'my_AJAX_processing_function');

//if you want none logged in users to access this function use this hook
add_action('wp_ajax_nopriv_ACTION_NAME', 'my_AJAX_processing_function');

et si vous souhaitez que les utilisateurs connectés et les visiteurs non connectés aient accès à cette fonction, utilisez les deux points d'ancrage (SECOND CHECK).

ensuite, dans votre fonction ajax, la première chose à faire est de vérifier le référant ajax (TROISIÈME CONTRÔLE):

function my_AJAX_processing_function(){
   check_ajax_referer('my_ajax_nonce');
   //do stuff here
}

next lors de l'exécution de requêtes sur la base de données avec une entrée utilisateur, vous devez utiliser $wpdb->prepare pour l'échappement et la validation plutôt que:

$query = "SELECT `id` FROM table WHERE `user_id` = $myid;";
$data = $wpdb->get_col( $query )

utilisation:

$data = $wpdb->query( $wpdb->prepare("SELECT `id` FROM table WHERE `user_id` = %d",$myid));
8
Bainternet

Je ne suis pas tout à fait sûr de la sécurité, mais les gestionnaires WordPress Ajax sont adaptés à l'utilisateur (je suppose que la demande est toujours demandée, les cookies sont donc vérifiés et si l'utilisateur est connecté, il est comptabilisé). Ainsi, vous pouvez faire l’archive current_user_can() habituelle.

2
Rarst

vraisemblablement on est connecté lors de cette demande? vous pouvez hacher des données et créer un nonce unique par utilisateur sur votre page, le transmettre avec votre demande ajax et le comparer à l'utilisateur connecté. ou peut-être que je ne comprends pas ce que vous faites ici.

0
Milo