web-dev-qa-db-fra.com

Comment valider correctement les données de $ _GET ou $ _REQUEST à l'aide de fonctions WordPress?

Je travaille sur un plugin qui nécessite une manipulation à la volée de la sortie du contenu. Cela dépend uniquement de la variable actuelle $_GET ou de la variable $_REQUEST.

Selon ce que la variable est définie, elle appellera une certaine méthode de classe pour gérer la demande de l'utilisateur et afficher le contenu approprié.

Je suis tout à fait au courant de la page Validation des données du WordPress Codex. Cependant, je ne suis pas sûr de la meilleure approche à adopter pour mon scénario, ni pour aucun scénario de désinfection des variables $_GET ou $_REQUEST.

Comment puis-je désinfecter en utilisant les fonctions WordPress pour la variable $_GET ou la variable $_REQUEST pour une chaîne qui sera mise en correspondance pour appeler une méthode de classe spécifique?

Cela pourrait-il être exploité ou échouer avec le code suivant ?:

public function display_admin_page(){
    if(is_admin() && isset($_GET['page'])){
        global $content;
        $page = sanitize_title($_GET['page']);
        $method_name = 'page_'.str_replace('-', '_', $page);
        if(method_exists('content', $method_name)){
            // Display requested page from content class
            $thePage = $content->$method_name();
        } else{
            $thePage = $content->error(404);    
        }
        echo $thePage;
    }
}
4
Michael Ecklund

WordPress ne fournit aucune fonction spécifique de validation des données pour SUPERGLOBALS.

J'utilise la fonction PHP filter_input puis l'échappe comme n'importe quelle variable non fiable.

$url = filter_input( INPUT_GET, 'some_query_string', FILTER_VALIDATE_URL );

echo '<a href="'. esc_url( $url ). '">Click Me</a>';

L'entrée de filtre PHP accepte:

3
Chris_O

Pour votre exemple spécifique:

Vous avez nettoyé les données $ _GET de manière appropriée (je pensais utiliser sanitize_key au lieu de sanitize_title - vous ne pouvez pas dire qu'il y a une grande différence, mais sanitize_title est destiné à être utilisé dans les URL).

La fonction method_exists retournera true pour les méthodes privées et protégées. Ainsi, si un utilisateur tente d'appeler une méthode privée ou protégée, il échouera sans passer à la méthode 404. (À moins que la méthode display_admin_page ne soit dans la même classe.)

Cela nous amène au principal exploit potentiel: quiconque peut forcer n'importe quelle méthode publique de sa classe à s'exécuter. Si possible, il est toujours préférable d’inscrire spécifiquement sur la liste blanche ce qui peut être accepté. De cette façon, vous pouvez valider avec quelque chose comme:

if ( !in_array( $_GET['page'], array( 'accepted_method', 'another_accepted_method' ) ) )
     $content->error(404);
2
SeventhSteel

La désinfection de $_GET dépend du contexte. Cela dépend de la valeur que vous souhaitez et de la manière dont vous souhaitez la valider.

Il n’existe pas de réponse universelle à cette question. C'est très spécifique au contexte. Par exemple, vous pouvez écrire une fonction qui supprime toutes les balises et les barres obliques, ce qui est très sûr, mais que faire si vous voulez qu'une balise p soit sauvegardée? Pas de mal là-bas. La famille wp_kses () est une étude intéressante, mais n’est pas une bonne solution, car elle prend en compte le contexte, le niveau d’utilisateur, etc. Par exemple, en tant qu'utilisateur administrateur, vous pouvez enregistrer JavaScript dans le titre et le contenu de l'article, mais vous ne pouvez pas utiliser un rôle moins important.

Si sa valeur est une quantité connue, vous pouvez également vérifier si in_array( $array_valid_strings ) et en être tout à fait sûr.

Cela dit, il existe différents degrés d'assainissement. Il est donc important de garder votre objectif final à l'esprit. Je consulterais cette liste et trouverais la fonction ou la combinaison de fonctions qui correspond à vos besoins. Ce sont précisément les fonctions sanitize_ qui doivent être utilisées ici, pas esc_. L'assainissement et l'évasion continuent d'être confondus ...

Dans mon cas, je vais utiliser sanitize_text_field () car il supprime une chaîne à partir des entrées utilisateur ou de la base de données.

  • Vérifie si UTF-8 n'est pas valide,
  • Convertit les caractères uniques <en entités
  • Strips tous les tags
  • Supprime les sauts de ligne, les tabulations et les espaces supplémentaires
  • Strips octets

Bonne chance :).

P.S. Cette réponse cite trois perspectives différentes de développeur (Josh, Michal, Kevin).

0
Ahmad Awais

Je recommanderais d'utiliser mysql_real_escape_string($_GET) pour toute demande GET. C'est une fonctionnalité très puissante PHP.

Vous pouvez ensuite utiliser str_replace() pour remplacer les caractères indésirables.

0
Ciprian