Requêtes préparées : nécessaire ou non?

Bonjour tout le monde,

Je débute dans le développement de Dolibarr pour un projet de stage, et étant un peu paranoïaque de la sécurité je me demandais s’il était nécessaire ou non de sécuriser les données entrées par l’utilisateur dans des formulaires via des requêtes SQL préparées, ou si l’utilisation de la fonction GETPOST au moment de la récupération des valeurs dans des variables était suffisante ?

D’après ce que j’ai vu du code, j’ai cru comprendre que ladite fonction gérait déjà pas mal de nettoyage (filtrage possible via les paramètres, regex), mais j’aurais souhaité avoir la confirmation de personnes qui s’y connaissent bien dans le domaine afin de ne pas faire de bêtises qui pourraient conduire à d’éventuelles failles de sécurité.

Pour information, je travaille en version 14.0.4.

Merci par avance pour vos réponses ! :slight_smile:

Il y a pas mal de sécurité nativement dans dolibarr sur les questions d’injection SQL (impossible de placer dans un meme champs les mot SELECT ou UPDATE, … avec un WHERE ou un FROM (j’ai bien galéré avec cela pour le dev de certains de mes modules…)
D’expérience les requêtes préparées sont toujours meilleurs que celle construite de toute pièce, pas uniquement pour des questions de sécurités.

1 « J'aime »

Bonjour Defrance, et merci pour ta réponse.

Je me permets donc de poser une seconde question liée au sujet : comment fait-on des requêtes préparées avec Dolibarr ?
J’ai essayé de transposer mes maigres connaissances en PHP à l’outil, mais je me retrouve avec une erreur :

$strSql = 'SELECT nom, address, zip, town FROM llx_societe WHERE rowid = :idsoc;';
$rqPrep = $db->db->prepare($strSql);
$rqPrep->bindValue(':idsoc', $intSociete, PDO::PARAM_INT);
$rqPrep->execute();
$arrData = $rqPrep->fetchAll();

Voilà un morceau de code que j’avais testé sur une requête toute simple pour récupérer des informations à partir d’un identifiant (récupérer plus haut dans le code).
Sauf qu’au moment de passer sur le bindValue, et j’ai le droit à un charmant message orange qui me dit « Fatal error: Call to a member function bindValue() on boolean ».

Après des tests, je remarque qu’il y a un soucis sur la ligne $rqPrep = $db->db->prepare($strSql); qui me retourne false, d’où le fait que je ne puisse pas appliquer le bindValue sur $rqPrep par la suite.
J’en déduis donc que je m’y prend mal pour préparer la requête.
Est-ce que tu pourrais (ou quelqu’un d’autre qui passe par là, je prends toutes les bonnes infos de tout le monde !) m’indiquer la bonne syntaxe poru les requêtes préparées sous Dolibarr s’il te plaît ?

a priori il y a un db-> de trop …

Le soucis, c’est que si je retire le second « ->db » de ma ligne de code, je me retrouve avec une autre erreur : « Fatal error: Uncaught Error: Call to undefined method DoliDBMysqli::prepare() ».

J’ai comme l’impression que si je ne passe pas par $db->db, Dolibarr ne reconnaît pas que je souhaite interragir avec une base de données.

je viens de regarder dans le code dolibarr si il y avait des exemples de requetes préparées,
il semble passer par du pdo

1 « J'aime »

Bonjour @PierreGB

Vous devriez regarder comment çà se passe avec le module ModuleBuilder/RAD dans les dernière version. C’est pas parfait, mais la couche d’abstraction avec la commonCreate/commonUpdate combiné avec la propriété tableau $fields est assez intéressante.

En version 14 le moduleBuilder/RAD existe aussi, et le code généré avec les versions plus récentes n’est pas rétro compatible, mais çà permet de s’inspirer.

Sur la question des requêtes paramétrées, $db n’est pas une instance de PHP PDO mais une classe spécifique à Dolibarr (avec une interface dolibarr/htdocs/core/db/DoliDB.class.php) qui va être implémenté en fonction du SGDB (dolibarr/htdocs/core/db/).
Autrement dit, il n’y a pas de d’implémentation de prepare/bindValue/execute dans Dolibarr. C’est des méthodes implémentées par PHP PDO, mais pas « Dolibarr way ».

2 « J'aime »

Bonjour,

Ce que je n’aime pas avec GETPOST, c’est que la variable est nettoyée avant de pouvoir être validée. C’est la méthode Dolibarr.

Je pense qu’une variable doit pouvoir être validée avant d’être assainie et mise en forme, puis insérée dans une requête. C’est la raison pour laquelle je n’utilise jamais GETPOST pour mes modules.

Valider c’est très simple. Il s’agit simplement de vérifier que la valeur entrée correspond précisément (et j’insiste sur le mot précisément) à la valeur attendue en utilisant une succession de fonctions simples (is_numeric/string, ctype_alnum/alpha/digit pouvant être combiné à str_replace, > 0, in_array, empty, …).

Je trouve filter_input et filter_var un peu overkill mais ce sont des alternatives viables pour valider des variables.

Personnellement, j’aime faire en sorte que mon formulaire soit contenu dans un tableau récupérable en un seul appel à filter_input. Et ça permet d’isoler son code au passage. Tous les champs ont donc un nom du style mon_form[mon_champ].

Ensuite, assainir les variables, caster les entiers, les floats, appeler db->escape sur les chaînes…

Puis, construire la requête. Depuis quelques temps, je m’amuse pas mal avec Heredoc pour ça.

On peut assainir en construisant la requête, c’est ce qui se fait le plus souvent, mais je trouve que ça demande beaucoup de concaténations. C’est à toi de voir.

1 « J'aime »

Bonjour Defrance, FHenry et C3do,

Merci beaucoup pour vos réponses, ça me permet d’y voir un peu plus clair et de comprendre mon erreur d’interprétation de la « nature » de $db.

Actuellement il n’est pas prévu de faire une mise à jour de Dolibarr, car l’entreprise pour laquelle je fais le module n’a pas envie de risquer des dysfonctionnements en passant sur une version plus récente. Ils préfèrent rester en 14, et comme je découvre Dolibarr avec ce stage, je ne me permettrais pas de leur conseiller une telle chose, je n’ai aucunement les connaissances requises pour rattraper d’éventuels dysfonctionnements qui pourraient survenir !

Merci également pour les précisions sur le GETPOST. Je vais peut-être voir pour réécrire le code déjà entré afin d’avoir plus de « contrôle » sur les données que je récupère (et en plus ça sera plus pertinent pour le rapport de stage).

Donc encore une fois, merci pour vos explications et vos conseils !

Bonjour PierreGB,

Merci pour la création de ce sujet qui m’a grandement aidé pour le développement de mes compétences en dolibarr.
Étant moi même en stage actuellement, j’aimerais s’il vous plaît avoir vos retours d’expériences sur le sujet et si possible un extrait de votre rapport pour m’inspirer.
Merci