J'avoue pour ma part que je n'aime pas trop les is_numeric ou les cast (question de gout).... Ce que je fais généralement pour mes requêtes SQL c'est que je les stocke dans des constantes que j'utilises avec sprintf derrière.
j'ai donc un fichier avec toutes mes définitions SQL (généralement un fichier .sql.php par objet qui a besoin de SQL)
define("SQL_INSERT_TOTO","insert into toto (nom, valeur) values ('%s',%d')");
après $qry=sprintf(SQL_INSERT_TOTO, $nom, $valeur)
Dans ce cas c'est sprintf qui vérifie la cohérence des données par rapport à leur type. L'autre avantage (qui n'est en aucun cas lié aux injections SQL), c'est que mes requêtes sont toutes stockées dans des fichiers séparés. Si pour une raison ou une autre on veut changer de type de base de données et qu'il faut revoir les requêtes pas toujours forcément portables, c'est plus facile....
Attention ! cette méthode ne permet pas d'éviter toute injection SQL (ça se saurait !), mais permet au moins de faire des vérifications de type sur les valeurs passées aux requêtes.
Un autre solution que j'utilise est l'utilisation d'un ORM (object relationnal mapper) qui se charge de générer les requêtes en fonction d'une définition XML et qui du coup se charge aussi des vérification de type mais aussi d'étendue (possibilité de min/max etc...)
J'avoue pour ma part que je n'aime pas trop les is_numeric ou les cast
(question de gout).... Ce que je fais généralement pour mes requêtes
SQL c'est que je les stocke dans des constantes que j'utilises avec
sprintf derrière.
j'ai donc un fichier avec toutes mes définitions SQL (généralement
un fichier .sql.php par objet qui a besoin de SQL)
define("SQL_INSERT_TOTO","insert into toto (nom, valeur) values
('%s',%d')");
après
$qry=sprintf(SQL_INSERT_TOTO, $nom, $valeur)
Dans ce cas c'est sprintf qui vérifie la cohérence des données par
rapport à leur type. L'autre avantage (qui n'est en aucun cas lié aux
injections SQL), c'est que mes requêtes sont toutes stockées dans des
fichiers séparés. Si pour une raison ou une autre on veut changer de
type de base de données et qu'il faut revoir les requêtes pas
toujours forcément portables, c'est plus facile....
Attention ! cette méthode ne permet pas d'éviter toute injection SQL
(ça se saurait !), mais permet au moins de faire des vérifications de
type sur les valeurs passées aux requêtes.
Un autre solution que j'utilise est l'utilisation d'un ORM (object
relationnal mapper) qui se charge de générer les requêtes en
fonction d'une définition XML et qui du coup se charge aussi des
vérification de type mais aussi d'étendue (possibilité de min/max
etc...)
J'avoue pour ma part que je n'aime pas trop les is_numeric ou les cast (question de gout).... Ce que je fais généralement pour mes requêtes SQL c'est que je les stocke dans des constantes que j'utilises avec sprintf derrière.
j'ai donc un fichier avec toutes mes définitions SQL (généralement un fichier .sql.php par objet qui a besoin de SQL)
define("SQL_INSERT_TOTO","insert into toto (nom, valeur) values ('%s',%d')");
après $qry=sprintf(SQL_INSERT_TOTO, $nom, $valeur)
Dans ce cas c'est sprintf qui vérifie la cohérence des données par rapport à leur type. L'autre avantage (qui n'est en aucun cas lié aux injections SQL), c'est que mes requêtes sont toutes stockées dans des fichiers séparés. Si pour une raison ou une autre on veut changer de type de base de données et qu'il faut revoir les requêtes pas toujours forcément portables, c'est plus facile....
Attention ! cette méthode ne permet pas d'éviter toute injection SQL (ça se saurait !), mais permet au moins de faire des vérifications de type sur les valeurs passées aux requêtes.
Un autre solution que j'utilise est l'utilisation d'un ORM (object relationnal mapper) qui se charge de générer les requêtes en fonction d'une définition XML et qui du coup se charge aussi des vérification de type mais aussi d'étendue (possibilité de min/max etc...)
John GALLET
define("SQL_INSERT_TOTO","insert into toto (nom, valeur) values ('%s',%d')"); $qry=sprintf(SQL_INSERT_TOTO, $nom, $valeur) Quitte à t'emmerder à écrire ça comme ça, il vaut mieux utiliser les query
préparées si ton sgbdr le supporte, ça c'est vraiment bulletproof sur pas mal d'injections.
Dans ce cas c'est sprintf qui vérifie la cohérence des données par rapport à leur type. Y-a-t-il vraiment une différence de comportement entre le cast explicite
en php et le cast implicite exécuté par le %d du sprintf ?? Je l'ignore.
Un autre solution que j'utilise est l'utilisation d'un ORM (object relationnal mapper) qui se charge de générer les requêtes en fonction d'une définition XML et qui du coup se charge aussi des vérification de type mais aussi d'étendue (possibilité de min/max etc...)
Je pense en effet, même si je n'ai jamais eut le courage (syntaxiquement, c'est lourd à écrire), que la notion de descripteur de données permettant d'appliquer automatiquement des fonctions de filtrage et de vérification de cohérence sont une solution très intéressante pour automatiser et industrialiser la gestion des variables en entrée des scripts. Pour le moment, je me contente de générer automatiquement du code PHP à partir de fichiers descripteurs type CSV. En gros, je décris mes données sous openoffice/excel, je passe une moulinette awk dessus, et ça me crache du code du genre :
define("SQL_INSERT_TOTO","insert into toto (nom, valeur) values
('%s',%d')");
$qry=sprintf(SQL_INSERT_TOTO, $nom, $valeur)
Quitte à t'emmerder à écrire ça comme ça, il vaut mieux utiliser les query
préparées si ton sgbdr le supporte, ça c'est vraiment bulletproof sur pas
mal d'injections.
Dans ce cas c'est sprintf qui vérifie la cohérence des données par
rapport à leur type.
Y-a-t-il vraiment une différence de comportement entre le cast explicite
en php et le cast implicite exécuté par le %d du sprintf ?? Je l'ignore.
Un autre solution que j'utilise est l'utilisation d'un ORM (object
relationnal mapper) qui se charge de générer les requêtes en
fonction d'une définition XML et qui du coup se charge aussi des
vérification de type mais aussi d'étendue (possibilité de min/max
etc...)
Je pense en effet, même si je n'ai jamais eut le courage (syntaxiquement,
c'est lourd à écrire), que la notion de descripteur de données permettant
d'appliquer automatiquement des fonctions de filtrage et de vérification
de cohérence sont une solution très intéressante pour automatiser et
industrialiser la gestion des variables en entrée des scripts.
Pour le moment, je me contente de générer automatiquement du code PHP à
partir de fichiers descripteurs type CSV. En gros, je décris mes données
sous openoffice/excel, je passe une moulinette awk dessus, et ça me crache
du code du genre :
define("SQL_INSERT_TOTO","insert into toto (nom, valeur) values ('%s',%d')"); $qry=sprintf(SQL_INSERT_TOTO, $nom, $valeur) Quitte à t'emmerder à écrire ça comme ça, il vaut mieux utiliser les query
préparées si ton sgbdr le supporte, ça c'est vraiment bulletproof sur pas mal d'injections.
Dans ce cas c'est sprintf qui vérifie la cohérence des données par rapport à leur type. Y-a-t-il vraiment une différence de comportement entre le cast explicite
en php et le cast implicite exécuté par le %d du sprintf ?? Je l'ignore.
Un autre solution que j'utilise est l'utilisation d'un ORM (object relationnal mapper) qui se charge de générer les requêtes en fonction d'une définition XML et qui du coup se charge aussi des vérification de type mais aussi d'étendue (possibilité de min/max etc...)
Je pense en effet, même si je n'ai jamais eut le courage (syntaxiquement, c'est lourd à écrire), que la notion de descripteur de données permettant d'appliquer automatiquement des fonctions de filtrage et de vérification de cohérence sont une solution très intéressante pour automatiser et industrialiser la gestion des variables en entrée des scripts. Pour le moment, je me contente de générer automatiquement du code PHP à partir de fichiers descripteurs type CSV. En gros, je décris mes données sous openoffice/excel, je passe une moulinette awk dessus, et ça me crache du code du genre :
Un autre solution que j'utilise est l'utilisation d'un ORM (object relationnal mapper) qui se charge de générer les requêtes en fonction d'une définition XML et qui du coup se charge aussi des vérification de type mais aussi d'étendue (possibilité de min/max etc...)
C'est un ORM fait maison ou bien un projet public ? Je cherche depuis longtemps en ORM pour PHP mais je n'ai jamais trouvé mon bonheur, la plupart ayant plus d'inconvenients que d'avantages.
Il y a bien celui de Copix, mais on n'a pas toujours besoin d'utiliser le framework en entier.
Un autre solution que j'utilise est l'utilisation d'un ORM (object
relationnal mapper) qui se charge de générer les requêtes en
fonction d'une définition XML et qui du coup se charge aussi des
vérification de type mais aussi d'étendue (possibilité de min/max
etc...)
C'est un ORM fait maison ou bien un projet public ?
Je cherche depuis longtemps en ORM pour PHP mais je n'ai jamais trouvé
mon bonheur, la plupart ayant plus d'inconvenients que d'avantages.
Il y a bien celui de Copix, mais on n'a pas toujours besoin d'utiliser
le framework en entier.
Un autre solution que j'utilise est l'utilisation d'un ORM (object relationnal mapper) qui se charge de générer les requêtes en fonction d'une définition XML et qui du coup se charge aussi des vérification de type mais aussi d'étendue (possibilité de min/max etc...)
C'est un ORM fait maison ou bien un projet public ? Je cherche depuis longtemps en ORM pour PHP mais je n'ai jamais trouvé mon bonheur, la plupart ayant plus d'inconvenients que d'avantages.
Il y a bien celui de Copix, mais on n'a pas toujours besoin d'utiliser le framework en entier.
John GALLET
Re,
C'est la SEULE et unique solution (par exemple en castant). Je trouve que caster la variable n'est pas forcément la meilleure solution.
Je suis d'accord. J'ai juste indiqué que a priori (comprendre : je ne connais pas de contournement à l'heure actuelle mais ça veut pas dire qu'il n'y en a pas...), en termes de sécurité, ça doit suffire à prévenir une injection SQL sur un entier, ce qui n'est pas le cas d'autres pratiques.
Le travail de vérification des variables doit se faire en amont et a C'est pas moi qui dirait le contraire, ça fait **des années** que je
répète qu'il faut des fonctions de filtrage. cf le cours que je diffuse sur www.saphirtech.com pour plus d'infos.
plus a voir avec la cohérence de l'application que la sécurité. Les deux, et de toutes façons c'est un tout indissociable.
fait un cast, on laisse le script s'exécuter alors qu'il y a incohérence des données entrées par l'utilisateur, il devient alors difficile de ramener une erreur précise à l'utilisateur. Ca c'est encore un autre sujet.
Bon, ça ne fonctionne pas chez moi ( MySQL 4.0.23 - Linux Debian ), mais je saurais maintenant que certaines versions de MySQL sont vulnérables.
Alors ça a peut-être été patché : mysql Ver 11.18 Distrib 3.23.58, for pc-linux (i686) (marrant il me semblait avoir installé un truc plus récent... oui mais sur quelle machine... ??? Gronf.)
Mais oui, nécessairement il y a des versions vulnérables. Et de toutes façons, à la base (c'est le cas de le dire) on n'écrit pas volontairement du SQL incorrect en espérant que le SGBDR l'accepte sous un (faux) prétexte de sécurité. Y'en a marre des mauvaises réponses aux bonnes questions (comme register_globals ou magic_quotes). Si on s'attend à avoir un entier, on vérifie, comme vous le disiez, en amont, que c'est bien un entier (ou au moins un numérique).
a++; JG
Re,
C'est la SEULE et unique solution (par exemple en castant).
Je trouve que caster la variable n'est pas forcément la meilleure solution.
Je suis d'accord. J'ai juste indiqué que a priori (comprendre : je ne
connais pas de contournement à l'heure actuelle mais ça veut pas dire
qu'il n'y en a pas...), en termes de sécurité, ça doit suffire à prévenir
une injection SQL sur un entier, ce qui n'est pas le cas d'autres
pratiques.
Le travail de vérification des variables doit se faire en amont et a
C'est pas moi qui dirait le contraire, ça fait **des années** que je
répète qu'il faut des fonctions de filtrage. cf le cours que je
diffuse sur www.saphirtech.com pour plus d'infos.
plus a voir avec la cohérence de l'application que la sécurité.
Les deux, et de toutes façons c'est un tout indissociable.
fait un cast, on laisse le script s'exécuter alors qu'il y a incohérence
des données entrées par l'utilisateur, il devient alors difficile de
ramener une erreur précise à l'utilisateur.
Ca c'est encore un autre sujet.
Bon, ça ne fonctionne pas chez moi ( MySQL 4.0.23 - Linux Debian ), mais
je saurais maintenant que certaines versions de MySQL sont vulnérables.
Alors ça a peut-être été patché :
mysql Ver 11.18 Distrib 3.23.58, for pc-linux (i686) (marrant il me
semblait avoir installé un truc plus récent... oui mais sur quelle
machine... ??? Gronf.)
Mais oui, nécessairement il y a des versions vulnérables. Et de toutes
façons, à la base (c'est le cas de le dire) on n'écrit pas volontairement
du SQL incorrect en espérant que le SGBDR l'accepte sous un (faux)
prétexte de sécurité. Y'en a marre des mauvaises réponses aux bonnes
questions (comme register_globals ou magic_quotes). Si on s'attend à avoir
un entier, on vérifie, comme vous le disiez, en amont, que c'est bien un
entier (ou au moins un numérique).
C'est la SEULE et unique solution (par exemple en castant). Je trouve que caster la variable n'est pas forcément la meilleure solution.
Je suis d'accord. J'ai juste indiqué que a priori (comprendre : je ne connais pas de contournement à l'heure actuelle mais ça veut pas dire qu'il n'y en a pas...), en termes de sécurité, ça doit suffire à prévenir une injection SQL sur un entier, ce qui n'est pas le cas d'autres pratiques.
Le travail de vérification des variables doit se faire en amont et a C'est pas moi qui dirait le contraire, ça fait **des années** que je
répète qu'il faut des fonctions de filtrage. cf le cours que je diffuse sur www.saphirtech.com pour plus d'infos.
plus a voir avec la cohérence de l'application que la sécurité. Les deux, et de toutes façons c'est un tout indissociable.
fait un cast, on laisse le script s'exécuter alors qu'il y a incohérence des données entrées par l'utilisateur, il devient alors difficile de ramener une erreur précise à l'utilisateur. Ca c'est encore un autre sujet.
Bon, ça ne fonctionne pas chez moi ( MySQL 4.0.23 - Linux Debian ), mais je saurais maintenant que certaines versions de MySQL sont vulnérables.
Alors ça a peut-être été patché : mysql Ver 11.18 Distrib 3.23.58, for pc-linux (i686) (marrant il me semblait avoir installé un truc plus récent... oui mais sur quelle machine... ??? Gronf.)
Mais oui, nécessairement il y a des versions vulnérables. Et de toutes façons, à la base (c'est le cas de le dire) on n'écrit pas volontairement du SQL incorrect en espérant que le SGBDR l'accepte sous un (faux) prétexte de sécurité. Y'en a marre des mauvaises réponses aux bonnes questions (comme register_globals ou magic_quotes). Si on s'attend à avoir un entier, on vérifie, comme vous le disiez, en amont, que c'est bien un entier (ou au moins un numérique).
a++; JG
Marc
C'est un ORM fait maison ou bien un projet public ? Je cherche depuis longtemps en ORM pour PHP mais je n'ai jamais trouvé mon bonheur, la plupart ayant plus d'inconvenients que d'avantages.
Il y a bien celui de Copix, mais on n'a pas toujours besoin d'utiliser le framework en entier.
dans la bibliotheque Pear, il y en a 2 si je ne me trompes pas. J'utilise l'un des 2 avec quelques modifications personnelles. C'est le terme de DAO qui est utilisé dans ce cas, je suppose que ca revient au meme non ?
http://pear.php.net/package/DB_DataObject
C'est un ORM fait maison ou bien un projet public ?
Je cherche depuis longtemps en ORM pour PHP mais je n'ai jamais trouvé
mon bonheur, la plupart ayant plus d'inconvenients que d'avantages.
Il y a bien celui de Copix, mais on n'a pas toujours besoin d'utiliser
le framework en entier.
dans la bibliotheque Pear, il y en a 2 si je ne me trompes pas.
J'utilise l'un des 2 avec quelques modifications personnelles.
C'est le terme de DAO qui est utilisé dans ce cas, je suppose
que ca revient au meme non ?
C'est un ORM fait maison ou bien un projet public ? Je cherche depuis longtemps en ORM pour PHP mais je n'ai jamais trouvé mon bonheur, la plupart ayant plus d'inconvenients que d'avantages.
Il y a bien celui de Copix, mais on n'a pas toujours besoin d'utiliser le framework en entier.
dans la bibliotheque Pear, il y en a 2 si je ne me trompes pas. J'utilise l'un des 2 avec quelques modifications personnelles. C'est le terme de DAO qui est utilisé dans ce cas, je suppose que ca revient au meme non ?
http://pear.php.net/package/DB_DataObject
ftc
Et de toutes façons, à la base (c'est le cas de le dire) on n'écrit pas volontairement du SQL incorrect en espérant que le SGBDR l'accepte sous un (faux) prétexte de sécurité.
Je tiens à préciser que de mettre entre quote des integer n'est pas du SQL incorrect, la norme SQL 92 précise que l'on peut ne pas mettre de quotes pas qu'il ne faut pas en mettre.
Et de toutes
façons, à la base (c'est le cas de le dire) on n'écrit pas volontairement
du SQL incorrect en espérant que le SGBDR l'accepte sous un (faux)
prétexte de sécurité.
Je tiens à préciser que de mettre entre quote des integer n'est pas du
SQL incorrect, la norme SQL 92 précise que l'on peut ne pas mettre de
quotes pas qu'il ne faut pas en mettre.
Et de toutes façons, à la base (c'est le cas de le dire) on n'écrit pas volontairement du SQL incorrect en espérant que le SGBDR l'accepte sous un (faux) prétexte de sécurité.
Je tiens à préciser que de mettre entre quote des integer n'est pas du SQL incorrect, la norme SQL 92 précise que l'on peut ne pas mettre de quotes pas qu'il ne faut pas en mettre.
John Gallet
Je tiens à préciser que de mettre entre quote des integer n'est pas du SQL incorrect,
Affirmation toute théorique et donc gratuite : va dire ça à Sybase ou à toute version d'Oracle antérieure à une 8.1. (de mémoire le numéro de version, en tous cas, quand j'ai appris le SQL sur une 6.x, t'avais pas intérêt). Historiquement, quoter les entiers égal erreur de parsing.
la norme SQL 92
C'est pas une norme c'est un standard, et donc comme de tous les standards on s'en fout complètement, ce qui importe c'est la manière dont les SGBDR qu'on emploie réellement sont implémentés. Quand on écrit une application multi-sgbdr, c'est déjà suffisement chiant de gérer les jointures externes et les opérations sur les dates, s'il faut gérer le quotage des entiers, halte aux conneries.
JG
Je tiens à préciser que de mettre entre quote des integer n'est pas du
SQL incorrect,
Affirmation toute théorique et donc gratuite : va dire ça à Sybase ou à
toute version d'Oracle antérieure à une 8.1. (de mémoire le numéro de
version, en tous cas, quand j'ai appris le SQL sur une 6.x, t'avais pas
intérêt). Historiquement, quoter les entiers égal erreur de parsing.
la norme SQL 92
C'est pas une norme c'est un standard, et donc comme de tous les
standards on s'en fout complètement, ce qui importe c'est la manière
dont les SGBDR qu'on emploie réellement sont implémentés. Quand on écrit
une application multi-sgbdr, c'est déjà suffisement chiant de gérer les
jointures externes et les opérations sur les dates, s'il faut gérer le
quotage des entiers, halte aux conneries.
Je tiens à préciser que de mettre entre quote des integer n'est pas du SQL incorrect,
Affirmation toute théorique et donc gratuite : va dire ça à Sybase ou à toute version d'Oracle antérieure à une 8.1. (de mémoire le numéro de version, en tous cas, quand j'ai appris le SQL sur une 6.x, t'avais pas intérêt). Historiquement, quoter les entiers égal erreur de parsing.
la norme SQL 92
C'est pas une norme c'est un standard, et donc comme de tous les standards on s'en fout complètement, ce qui importe c'est la manière dont les SGBDR qu'on emploie réellement sont implémentés. Quand on écrit une application multi-sgbdr, c'est déjà suffisement chiant de gérer les jointures externes et les opérations sur les dates, s'il faut gérer le quotage des entiers, halte aux conneries.