Lors de la jonction de tables, j'utilise des modèles SQL de Zend Framework. À titre d'exemple, j'ai modifié mon code actuel, mais je pense que vous obtiendrez le point:
$this->getSelect()->join(
array('sections' => $sectionsTableName),
'main_table.banner_id = pages.banner_id',
array()
)
->where("sections.section= '$section' OR sections.section = '0' OR (sections.section = '6' AND ? LIKE main_table.url)",$url)
->group('main_table.banner_id');
La page est chargée avec ajax et le paramètre $ section est envoyé en tant que paramètre GET ( www.example.com/controllerName/index/display/3?paremeter1=example§ion=www.example2.com
).
Voici maintenant le problème si quelqu'un effectue quelque chose comme ceci:
www.example.com/controllerName/index/display/3?paremeter1=example&url=(SELECT 3630 FROM(SELECT COUNT(*),CONCAT(0x7170786a71,(SELECT (ELT(3630=3630,1))),0x717a716b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)
De cette façon, l'utilisateur peut vider la base de données entière. Les données ne seront pas affichées, mais SQL effectuera toujours un vidage qui peut entraîner une surcharge sql.
Des questions:
- Quelle est la meilleure façon de prévenir un tel scénario?
- Maintenant, je suis inquiet pour les clients précédents. Est-il possible avec ce code de faire encore plus de risques, comme supprimer ou modifier une table? Je suppose que non parce que vous ne pouvez pas mettre d'autre instruction que SELECT dans la sous-sélection afin que DELETE produise une erreur de syntaxe sql. Ai-je raison?
MISE À JOUR: Mon exemple n'est pas une bonne illustration de l'injection SQL car il y a des sections «signe autour de $ et donc il ne sera pas possible de faire l'injection. Quoi qu'il en soit, cela serait possible lorsque vous attendez une valeur entière et lorsque vous ne filtrez pas l'entrée entière. Voir mon commentaire ci-dessous.
la source
$db = Mage::getSingleton('core/resource')->getConnection('core_read');
et$db->quote()
même dans votre cas, regardez$db->quoteInto
. Si$this
est une ressource, vous pouvez le faire:$this->getConnection('core_read')->quoteInto()
si elle est une collection que vous pourriez faire:$this->getResource()->getConnection('core_read')->quoteInto()
. le long de ces lignes. Si cela vous guide vers votre objectif.'
signe avant(
signe et donc(SELECT
ou quoi que ce soit d'autre sera juste une chaîne et ne fonctionnera pas. Lorsque le champ est entier, il'
n'est pas nécessaire et cela rend possible un tel scénario. Mais l'entier doit toujours être filtré avecintval()
donc ce n'est pas non plus un problème.'
? Alors' AND (SELECT ...) '
? Soit dit en passant, je ne pense pas que Zend ne cite pas cela ... Et si vous utilisez des liaisons, PDO s'en occupera."sections.section= '$section'"
Réponses:
Validez votre entrée!
Aussi bien et autant que possible.
Quelques suggestions pour votre validation:
Vérifiez la longueur de la variable que vous obtenez via le paramètre GET. Il n'est pas nécessaire d'accepter une longue chaîne sans fin.
Validez pour un nom de domaine. Quel type de format ont vos noms de domaine attendus? Est-ce toujours www.mydomain.tld? Créez une expression régulière qui vérifie une correspondance ou (mieux) une utilisation
Zend_Validate_Hostname
:Liste blanche: savez-vous à quels noms de domaine s'attendre? Vous pouvez créer une liste de domaines autorisés et les comparer. Laissez tomber le reste.
Liste noire des noms de domaine et / ou des caractères: Si vous attendez un nom de domaine, il n'est pas nécessaire d'accepter d'autres caractères que az et 0-9 et "." (sauf si vous travaillez avec des noms de domaine spéciaux).
la source