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;
}
}
$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:
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);
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.
Bonne chance :).
P.S. Cette réponse cite trois perspectives différentes de développeur (Josh, Michal, Kevin).
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.