Je viens d'hériter d'un projet car le dernier développeur est parti. Le projet est construit à partir de Code Igniter. Je n'ai jamais travaillé avec Code Igniter auparavant.
J'ai jeté un coup d'œil au code et je vois des appels de base de données dans le contrôleur comme ceci:
$dbResult = $this->db->query("SELECT * FROM users WHERE username = '".$_POST['user_name']."'");
ou des appels comme celui-ci:
$dbResult = $this->db->query("SELECT * FROM users WHERE username = '".$this->input->post('username')."'");
L'igniteur de code nettoie-t-il automatiquement ces requêtes pour empêcher l'injection SQL?
CodeIgniter ÉCHAPPE les variables que vous passez lorsque vous utilisez le $this->db->query
méthode. Mais UNIQUEMENT lorsque vous transmettez les variables sous forme de liaisons, voici un exemple:
$dbResult = $this->db->query("SELECT * FROM users WHERE username = '?'", array($this->input->post('username')));
N'oubliez pas non plus que $_POST
ne devrait pas être préféré à $this->input->post
car il vérifie si les variables existent pour éviter les erreurs.
CodeIgniter fournit quelques fonctions d'échappement de chaîne dans sa couche de base de données.
Extrait de Manuel CI :
C'est une très bonne pratique de sécurité que d'échapper à vos données avant de les soumettre à votre base de données. CodeIgniter a trois méthodes qui vous aident à faire ceci:
$ this-> db-> escape () Cette fonction détermine le type de données afin qu'elle puisse échapper uniquement les données de chaîne. Il ajoute également automatiquement des guillemets simples autour des données afin que vous n'ayez pas à:
$sql = "INSERT INTO table (title) VALUES(".$this->db->escape($title).")";
Je publierais les deux autres exemples, mais je ne voudrais pas retirer tout le plaisir de lire le manuel.
Non, le code que vous avez publié est susceptible d'être injecté SQL. Vous devez utiliser liaison de requête pour construire vos requêtes SQL. Si vous utilisez la bibliothèque CI DB, vous la coderiez quelque chose comme ceci (exemple du guide de l'utilisateur):
$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";
$this->db->query($sql, array(3, 'live', 'Rick'));
Non, CodeIgniter ne nettoiera pas comme par magie les requêtes qui ont été construites comme ceci.
Selon les documents de CI ici , le framework filtre POST sur la construction du contrôleur. Il effectue également le filtrage XSS en option en appelant manuellement la fonction ou en définissant une configuration globale.
Je n'ai jamais utilisé CI non plus, sauf pour jouer avec, donc je ne sais pas jusqu'où je ferais confiance.
Utilisez l'enregistrement actif pour la sécurité et un codage plus facile:
Plutôt que:
$dbResult = $this->db->query("SELECT * FROM users WHERE username'".$_POST['user_name']."'");
Utilisation (même résultat):
$this->db->where('username',$this->input->post('user_name');
$dbResult = $this->db->get('users');
Vous devez utiliser $ this-> input-> post, la liaison de requête et l'enregistrement actif pour obtenir les données les plus sûres, puis toujours tester test test pour être sûr.
Cela n'échappe à rien. Il vaut mieux le changer pour la syntaxe de liaison ou la syntaxe d'enregistrement active
Utilisation de la fonction d'échappement pour l'injection de CI
<?php $username = $this->input->post('username');
$query = 'SELECT * FROM subscribers_tbl WHERE user_name = '.$this->db->escape($email);
$this->db->query($query);?>
The docs for (at least) 2.2 state, in a big red box:
Bien que Active Record fasse de son mieux pour citer correctement les noms de champ et de table que vous lui fournissez, notez qu'il n'est PAS conçu pour fonctionner avec des entrées utilisateur arbitraires. NE PAS l'alimenter avec des données utilisateur non désinfectées.
Ce qui pour ce programmeur signifie "ne comptez pas sur Active Record pour citer quoi que ce soit ".
Cela peut être pénible, mais vous devez convertir vos requêtes en enregistrement actif.
Je copie du manuel CodeIgniter: "Au-delà de la simplicité, un avantage majeur de l'utilisation des fonctionnalités Active Record est qu'il vous permet de créer des applications indépendantes de la base de données, car la syntaxe de la requête est générée par chaque adaptateur de base de données . Il permet également des requêtes plus sûres, car les valeurs sont automatiquement échappées par le système. "
Et comme certaines personnes l'ont déjà dit, oui, ce code est sensible à l'injection SQL
Optimisé avec un deuxième post param (TRUE) pour filtrer XSS au niveau d'entrée:
$this->db->where('username',$this->input->post('user_name', TRUE);
$dbResult = $this->db->get('users');