IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Eviter les injections sql oracle


Sujet :

PHP & Base de données

  1. #1
    Membre actif
    Inscrit en
    Avril 2007
    Messages
    483
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Avril 2007
    Messages : 483
    Points : 234
    Points
    234
    Par défaut Eviter les injections sql oracle
    Bonjour,

    Je voudrais savoir s'il existe une fonction php ou une méthode pour éviter les injections sql depuis un formulaire classique vers une base de données oracle

    Je sais qu'il existe une fonction php qui fait cela pour les bases de données MySQL mais je n'ai encore rien trouvé pour faire la même chose avec les bases de données oracle.

    Quelqu'un s'est-il déjà penché sur la question ?

    Merci d'avance pour vos réponses

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Points : 220
    Points
    220
    Par défaut
    Le mieux est d'utiliser des requêtes préparées, car cela empêche toute injection SQL et de plus permet d'utiliser le cache de requêtes d'Oracle (Shared Pool) au mieux, et ce gratuitement .

    En gros quelque soit le langage, il faut avec Oracle toujours utiliser des requêtes préparées si on veut une appli qui tienne la route avec pas mal d'utilisateurs. (je peux détailler si tu veux)

    Et le top (à mon sens) c'est d'utiliser des procédures stockées PL/SQL appelées via des requêtes préparées.

    Quelle API utilises-tu pour te connecter à Oracle : OCI8 ? PDO ?

  3. #3
    Membre actif
    Inscrit en
    Avril 2007
    Messages
    483
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Avril 2007
    Messages : 483
    Points : 234
    Points
    234
    Par défaut
    J'utilise OCI8

    Si j'ai bien compris ce que tu me dis concerne les requetes que j'exécute lors du chargement d'une page, or ce que je voudrais c'est éviter les requetes SQL saisies dans les champs d'un formulaire

    Ou bien je me trompe ^^"

    A vrai dire je n'ai pas très bien compris tous ces termes que tu as dis (comme procédures stockées ou requetes préparées)

    Je ne connais pas très bien oracle je l'utilise car on m'a demandé de créer une appli avec oracle pour abse de données, sinon j'utilise plus couramment MySQL pour les appli php.

    Je veux bien que tu détailles plus s'il te plait ^^

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Points : 220
    Points
    220
    Par défaut
    Pas de problème .

    Une requête préparée est une requête SQL où on définit des emplacements pour chaque paramètre de la requête.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT nom, prenom FROM Utilisateur WHERE IdUtilisateur = :nomutilisateur;
    Ensuite on "bind" chaque emplacement à une variable PHP, en donnant le type du champ SQL.

    Une procédure stockée est une fonction enregistrée sur le serveur de base de données, compilée. L'utilisation de SP (stored procedures) a de très nombreux avantages sous Oracle (moins sous MySQL) en termes de performances et de sécurité. Si tu souhaites en utiliser je pourrai te montrer des exemples, et tu peux notamment aller sur le forum PL/SQL de developpez.com. Par exemple : http://www.developpez.net/forums/sho...d.php?t=584065 où il y a une belle procédure

    Avant un exemple, je te montre l'API que je me suis créée au-dessus d'OCI8 pour me simplifier grandement la tâche dans toutes mes pages PHP :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    <?php 
     
        include 'connexion.inc.php';
     
        define('NB_RES_PAR_PAGE', 10);
     
        function fct_bd_connexion($strTypeCnx = "ADMIN")
        {
            if ($strTypeCnx == "ADMIN")
            {
                $conn = oci_connect(ORA_CON_NOM_ADMIN, ORA_CON_MDP_ADMIN, ORA_CON_BD);
            }
            else if ($strTypeCnx == "SITE")
            {
                $conn = oci_connect(ORA_CON_NOM_SITE, ORA_CON_MDP_SITE, ORA_CON_BD);
            }
            fct_bd_gerer_erreurs(null, $conn, __FILE__, __LINE__, "erreurbd.php");
     
            return $conn;
        }
     
        function fct_bd_deconnexion($conn)
        {
            oci_close($conn);
        }
     
        function fct_bd_gerer_erreurs($bres, $res, $file, $line, $strPageErreur)
        {
            if (!$bres)
            {
                $err = $res ? oci_error($res) : oci_error();
                if (isset($err['message'])) 
                {
                    //$m = htmlentities(substr($err['message'], strpos($err['message'], ":") + 2, strpos($err['message'], "\n") - strpos($err['message'], ": ") - 2));
                    $m = htmlentities(substr($err['message'], strpos($err['message'], ":") + 2));
                    //$m = htmlentities($err['message']);
                    $_SESSION['msgerreur'] = $m;
                    header ("Location: $strPageErreur");
                    exit;
                } 
            }
        }
     
        function fct_bd_call_sp($conn, $statement, &$bindvars, $strPageErreur = "erreurbd.php")
        {
            $stid = oci_parse($conn, $statement);
     
            // On lie les variables PHP à la requête
            foreach ($bindvars as $b) 
            {
                // On crée une variable locale avec comme nom celui passé en paramètre
                $$b[0] = $b[1];  
                // oci_bind_by_name(resource, bv_name, php_variable, length, type)
                $r = oci_bind_by_name($stid, ":$b[0]", $$b[0], $b[2], $b[3]); 
                fct_bd_gerer_erreurs($r, $stid, __FILE__, __LINE__, "erreurbd.php");
            }
            $r = oci_execute($stid, OCI_DEFAULT);
     
            fct_bd_gerer_erreurs($r, $stid, __FILE__, __LINE__, "erreurbd.php");
     
            // puis on recopie les variables dans le tableau original pour récupérer
            // les valeurs en sortie des variables OUT et IN OUT
            for ($i=0; $i<count($bindvars); $i++)
            {
                $bindvars[$i][1] = $$bindvars[$i][0];
            }
     
            oci_free_statement($stid);
     
            fct_bd_gerer_erreurs($r, $stid, __FILE__, __LINE__, "erreurbd.php");
     
            return 1;
        }
     
        function fct_bd_creer_curseur($conn, $strPageErreur = "erreurbd.php")
        {
            $curs = oci_new_cursor($conn);
            fct_bd_gerer_erreurs($curs, $conn, __FILE__, __LINE__, "erreurbd.php");   
     
            return $curs;
        }
     
        function fct_bd_lire_curseur($curs, &$arrResults, $typefetch = OCI_FETCHSTATEMENT_BY_ROW, $strPageErreur = "erreurbd.php")
        {
            oci_execute($curs);
     
            $nbrows = oci_fetch_all($curs, $arrResults, null, null, $typefetch);
     
            if ($nbrows == false)
            {
                fct_bd_gerer_erreurs($nbrows, $curs, __FILE__, __LINE__, "erreurbd.php");
            }
     
            oci_free_statement($curs);
     
            return $nbrows;
        }
    ?>
    Les fonctions les plus utiles sont fct_bd_call_sp qui exécute une requête (je l'ai appelée call_sp car perso je ne fais qu'appeler des procédures stockées )et fct_bd_lire_curseur qui lit un curseur et renvoie le tableau résultat.

    Maintenant un exemple avec appel de procédure stockée qui renvoie deux curseurs, que l'on lit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    function fct_bd_membre_detailsprofil(
                    $conn, $strEmail, &$arrDetailsProfil, 
                    &$arrDetailsModifs, $strPageErreur = "presentation.php")
        {
            $curs_profil = fct_bd_creer_curseur($conn);
            $curs_modifs = fct_bd_creer_curseur($conn);
            $arrBindArgs = array();
     
            $strRequete = "BEGIN pkg_membre.DetailsProfil(:email, :cur_detailsprofil, :cur_detailsmodifs); END;";
     
            array_push($arrBindArgs, array('EMAIL', $strEmail, 150, null));   
            array_push($arrBindArgs, array('CUR_DETAILSPROFIL', $curs_profil, -1, OCI_B_CURSOR));
            array_push($arrBindArgs, array('CUR_DETAILSMODIFS', $curs_modifs, -1, OCI_B_CURSOR));
            fct_bd_call_sp($conn, $strRequete, $arrBindArgs, $strPageErreur);
     
            fct_bd_lire_curseur($curs_profil, $arrDetailsProfil, OCI_FETCHSTATEMENT_BY_COLUMN, $strPageErreur);
            fct_bd_lire_curseur($curs_modifs, $arrDetailsModifs, OCI_FETCHSTATEMENT_BY_COLUMN, $strPageErreur);
        }
    - on crée les deux curseurs en PHP
    - on initialise le tableau qui va contenir les variables liées (bind variables)
    - on construit la requête avec les emplacements de variables
    - on remplit le tableau des variables de liens
    - on exécute la requête
    - on lit les 2 curseurs

    Grâce à l'API, le code est beaucoup plus concis qu'en OCI8 direct.

    J'espère que c'est clair.

  5. #5
    Membre actif
    Inscrit en
    Avril 2007
    Messages
    483
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Avril 2007
    Messages : 483
    Points : 234
    Points
    234
    Par défaut
    Merci pour cette explication.

    C'est relativement clair, même si je ne comprends pas tout ^^" (mais avec un peu de recherche sur les fonctions ça devrait aller mieux ! )

    Je reviendrais te demander si j'opte pour cette solution et que je rencontre des soucis ^^

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Points : 220
    Points
    220
    Par défaut
    Sinon tu peux aussi jeter un coup d'oeil sur PDO pour Oracle. PDO est une interface commune d'accès aux SGBD en PHP : tu utiliserais exactement le même code pour MySQL et pour Oracle. Les requêtes préparées sont très simples à utiliser avec PDO.

    Par contre, tu seras un peu limité si tu utilises les procédures stockées (pas de retour de plusieurs curseurs en même temps par exemple ).

    N'hésites pas si tu as d'autres questions.

Discussions similaires

  1. [MySQL] Eviter les failles XSS et les injections SQL
    Par johnson95 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 09/09/2010, 15h30
  2. Questions sur les rêquetes sql oracle?
    Par naima2005 dans le forum SQL
    Réponses: 6
    Dernier message: 24/12/2007, 13h57
  3. Contrer les injections SQL
    Par bodysplash007 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 06/04/2007, 13h19
  4. [MySQL] besoin d'aide pour comprendre les injections sql
    Par cassy dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 28/01/2007, 14h21
  5. Lutter contre les injections SQL
    Par EvilAngel dans le forum ASP
    Réponses: 4
    Dernier message: 15/06/2006, 17h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo