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 :

échapper des valeurs $_POST servant à la connection


Sujet :

PHP & Base de données

  1. #1
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut échapper des valeurs $_POST servant à la connection
    Le code suivant est appelé en ajax,

    j'ai besoin de protéger et d'échapper les variables $POST notamment $user_id,

    mais cette variable user_id sert à me connecter, et donc la connection ne peut pas se faire car real_escape_string ne peut se faire sans connection.

    comment securiser autrement $user_id ? merci d'avance

    fichier 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
     
    <?php
    include ("dbconfig.php");
     
    error_reporting(E_ALL);
    ini_set("display_errors", 1);
    header("Access-Control-Allow-Origin: *");
     
    $user_id = $dbcon ->real_escape_string(strip_tags($_GET['user_id'],ENT_QUOTES));
    $current_file = $dbcon ->real_escape_string(strip_tags($_GET['current_file'],ENT_QUOTES));
    $user_token = $dbcon ->real_escape_string(strip_tags($_POST['user_token'],ENT_QUOTES));
     
     
    $geojson = array(
             'type'      => 'FeatureCollection',
             'features'  => array()
    );
    try {
     
           $dbcon = new PDO("pgsql:host=".$pghost.";port=".$pgport.";dbname=mfy_".$user_id.";user=".$pguser.";password=".$pgpass."");
            $dbcon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $stmt = $dbcon->prepare("SELECT cat, public.ST_AsGeoJSON(public.ST_Transform((geom),4326),6) AS geojson FROM :current_file._linestring");
            $stmt->bindValue(":currentfile", $current_file, PDO::PARAM_INT);
     
    if($stmt->execute()){
                    $id_count = 0;
                    while($rowset = $stmt->fetch(PDO::FETCH_ASSOC)){
                            $properties = $rowset;
                            unset($properties['geojson']);
                            unset($properties['geom']);
                                    $feature = array(
                                                     'type' => 'Feature',
                                                     'id' => $id_count,
     
                                                     'properties' => $properties,
                                                     'geometry' => json_decode($rowset['geojson'], true)
                                    );
                            array_push($geojson['features'], $feature);
                            $id_count++;
     
     
           }
                    header('Content-Type: application/json');
                    echo json_encode($geojson, JSON_NUMERIC_CHECK);
                    $dbcon = null;
                    exit;
            } else {
                    header('Content-Type: application/json');
                    echo json_encode($geojson, JSON_NUMERIC_CHECK);
                    $dbcon = null;
                    exit;
            }
    } catch (PDOException $e) {
            header('Content-Type: application/json');
            echo json_encode($geojson, JSON_NUMERIC_CHECK);
            $dbcon = null;
            exit;
    }
    ?>


    exemple type d'appel ajax depuis javascript : le traitement de la réponse n'est pas indiqué mais est maitrisé. Ce sont des variables en javascript qui sont envoyés à 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
    function rowcounter() {
    rowcount = $.ajax({
      url: "../crud/dataservice/count_tracks2.php",
      method: "GET",
      dataType: "json",
      data: {
          command: "LINESTRING",
    current_file: current_file,
              cat: "track1",
    user_id: user_id,
      },
      xhrFields: {
          withCredentials: true
      },
      username: null,
      password: null
    });
     
     
    //      response2 = rowcount.responseText;
    //      console.log(response2);
    };
    fichier dbconfig.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
     
    $pgconfig = array (
            "_pgsql_db_host_" => "localhost",
            "_pgsql_db_port_" => "5432",
            "_pgsql_db_user_" => "userpg",
            "_pgsql_db_pass_" => "mdpp",
            "_pgsql_db_name_" => "nothing" );
     
         $pghost = $pgconfig['_pgsql_db_host_'];
            $pgport = $pgconfig['_pgsql_db_port_'];
            $pguser = $pgconfig['_pgsql_db_user_'];
            $pgpass = $pgconfig['_pgsql_db_pass_'];
            $pgname = $pgconfig['_pgsql_db_name_'];
    ?>

  2. #2
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 322
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 322
    Billets dans le blog
    17
    Par défaut
    Tu ne confonds pas utilisateur BdD et utilisateur applicatif ?
    Comment tu connectes-tu à ta BdD dans dbconfig.php ?
    Généralement l'utilisateur se connectant au serveur de base de données est paramétré en dur côté applicatif et diffère de l'utilisateur applicatif.
    Si tu reçois vraiment l'utilisateur BdD depuis un formulaire alors tu peux l'utiliser directement pour la connexion sans l'échapper, car il n'y a pas de risque d'injection SQL.
    Ensuite, après connexion et si besoin de l'intégrer à une requête SQL, tu pourras l'échapper de manière habituelle.

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    721
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 721
    Par défaut
    Non, ne faites pas des trucs comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $user_token = $dbcon ->real_escape_string(strip_tags($_POST['user_token'],ENT_QUOTES));
    real_escape_string c'est une méthode du siècle dernier et de toute façon l'utiliser seule ne suffit pas (voir la doc).
    La fonction strip_tags est utilisée de manière abusive et ne sert pas à ça.
    L'essentiel est d'utiliser des requêtes préparées, ce que vous faites.

    Par contre je serais étonnée que la clause FROM accepte un paramètre au lieu d'une valeur "en dur". A mon avis il faut faire du SQL dynamique, en clair concaténer dans ce cas précis et il faut donc faire attention aux injections SQL.

    Vu que n'importe qui peut trafiquer le paramètre user_id et qu'il n"y a pas de contrôle des droits a priori, j'ai des réserves sur la sécurité. Je m'attendrais plutôt à une variable de session.

    On peut aussi éliminer tout le code répétitif. En réalité la gestion d'exception ne sert à rien, elle ne fait rien de spécial qui ne soit pas déjà fait ailleurs. Elle est même nuisible, car elle masque les exceptions qui pourraient intervenir. Il vaudrait mieux alors la supprimer.

  4. #4
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut
    Merci beaucoup. J'ai édité ce qui semblait manquer dans mon descriptif : appel en ajax et dbconfig.php

    L'utilisateur applicatif a son propre mot de passe, stocké sur mysql (capture suivante)

    et il y a une autre base de données postgresql qui correspond à l'utilisateur, mfy_numerodutilisateur, dont je suis le seul a avoir le code, et les données sont puisées dedans lorsque l'utilisateur a effectué la connection

    Vu que n'importe qui peut trafiquer le paramètre user_id et qu'il n"y a pas de contrôle des droits a priori, j'ai des réserves sur la sécurité. Je m'attendrais plutôt à une variable de session.
    C'est vrai, en ce moment, il suffit de changer user_id en javascript pour regarder ce que font les autres, la manière que je m'apprete a faire est de faire un contrôle de la valeur du token modifiée dans le tableau des utilisateurs quand l'utilisateur se connecte :

    Nom : screenshot-ee9b5a8b.jpg
Affichages : 160
Taille : 87,5 Ko

    Cette valeur étant donnée à l'utilisateur dans une variable javascript et renvoyée par ajax. Je veux donc comparer le token du tableau et celui que possède l'utilisateur pour m'assurer qu'il s'est bien connecté avec mot de passe, en comparant le ticket quil me presente et celui que j'ai stocké pour lui.

    Dans beaucoup des pages de mon site, inspiré de Leaflet Crud, l'utilisateur a des formulaires traités en javascript et html, avec des cases dans lequel il peut modifier ce qu'il ya dans les bases postgresql, c'est passé en $_POST

    j'ai cependant ces choses dans $_SESSION , à la connection :

    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
                        if (password_verify($_POST['user_password'], $result_row->user_password_hash)) {
     
     
    // write user data into PHP SESSION (a file on your server)
     
     
                            $_SESSION['user_name'] = $result_row->user_name;
                            $_SESSION['user_email'] = $result_row->user_email;
                            $_SESSION['user_id'] = $result_row->user_id;
                            $_SESSION['user_login_status'] = 1;
     
     
                            // creates and replaces the token in the database
     
    $sql5 = "UPDATE users SET token = '".base64_encode(random_bytes(10))."' WHERE user_id = ".$_SESSION['user_id'].";
    ";
     
    $query_token3 = $this->db_connection->query($sql5);
     
    // recupere ce token depuis la base de donnees
     
                    $sql6 = "SELECT token
                            FROM users
                            WHERE user_name = '" . $user_name . "' OR user_email = '" . $user_name . "';";
                    $get_token = $this->db_connection->query($sql6);
     
     
                        $result_row2 = $get_token->fetch_object();
     
    // recupere en tant que valeur de session
     
     
    $_SESSION['user_token'] = $result_row2->token;
    Par contre je serais étonnée que la clause FROM accepte un paramètre au lieu d'une valeur "en dur". A mon avis il faut faire du SQL dynamique, en clair concaténer dans ce cas précis et il faut donc faire attention aux injections SQL.
    Je ne maîtrise pas tout ça mais je vais chercher... je souhaite que FROM :current_file_linestring se transforme en FROM fichierdexemple_linestring

    enfin, Le code répetitif, issu de leaflet crud, a effectivement vocation a disparaître.

  5. #5
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut
    j'en suis la : mon code exemple est ici. je ne vous ai pas donné le meilleur exemple comme requete sql alors je l'ai modifiee :

    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
    <?php
     
    if(!isset($_SESSION)) {    session_start();  };
    include ("dbconfig.php");
     
    error_reporting(E_ALL);
    ini_set("display_errors", 1);
    header("Access-Control-Allow-Origin: *");
     
    $dbcon = new PDO("pgsql:host=".$pghost.";port=".$pgport.";dbname=mfy_".$_SESSION['user_id'].";user=".$pguser.";password=".$pgpass."");
    $dbcon -> setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
     
    $sql5 = "  UPDATE public.index SET name = ? WHERE name = ?;
            ALTER TABLE public.?_point RENAME TO ?_point;
    ALTER TABLE public.?_linestring RENAME TO ?_linestring;
    ALTER TABLE public.?_polygon RENAME TO ?_polygon;";
    $stmt=$dbcon->prepare($sql5);
    $stmt->execute(array(
            $_POST['newname'], $_POST['current_file'], $_POST['current_file'], $_POST['newname'], $_POST['current_file'], $_POST['newname'],  $_POST['current_file'],  $_POST['newname']));
              ?>


    l'erreur en ce moment apres modification, c'est la presence de guillemets simples :

    2023/07/31 09:34:52 [error] 533814#0: *19589 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught PDOException: SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "'normandie'"
    LINE 3: ALTER TABLE public.'normandie'_point
    ^ in /usr/share/nginx/html/crud/dataservice/rename_file.php:28
    Stack trace:
    #0 /usr/share/nginx/html/crud/dataservice/rename_file.php(28): PDOStatement->execute()
    #1 {main}

  6. #6
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 322
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 322
    Billets dans le blog
    17
    Par défaut
    $sql5 = " UPDATE public.index SET name = ? WHERE name = ?;
    ALTER TABLE public.?_point RENAME TO ?_point;
    ALTER TABLE public.?_linestring RENAME TO ?_linestring;
    ALTER TABLE public.?_polygon RENAME TO ?_polygon;";
    $stmt=$dbcon->prepare($sql5);
    Tu ne pourras pas utiliser les paramètres d'une requête préparée pour des noms d'objets.
    Ces paramètres ne servent que pour remplacer des valeurs littérales (chaînes/entiers/booléens/(NULL)).
    Il faudra sans doute revoir la modélisation de ta BdD.

  7. #7
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut
    Je vois...

    en effet quand un utilisateur veut renommer sa table, je lui permets actuellement de le faire, mais je ne devrais pas. Je devrais en revanche attribuer à chaque table son identifiant unique en chiffres, et à cet identifiant dans ma table "index" attribuer un surnom user_friendly qu'il peut renommer à sa guise : il ne verrai que le surnom, pas l'identifiant.

  8. #8
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 322
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 322
    Billets dans le blog
    17
    Par défaut
    Tu parles d'un utilisateur BdD ou d'un utilisateur applicatif ? (pas eu de réponse à cette question d'hier soir, et pour moi la situation n'est toujours pas claire)

    Un utilisateur applicatif ne devrait pas avoir "sa propre table", mais plutôt ses propres lignes au sein d'une table commune à tous les utilisateurs.

  9. #9
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    721
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 721
    Par défaut
    Oui, ce modèle est un peu bizarre. En général on ne crée pas des tables pour chaque utilisateur. Quelle est la motivation ?

  10. #10
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut
    Désolé ç'est un peu nouveau pour moi, mais je peux dire qu'il s'agit de

    le système est Leaflet Crud que j'ai modifié, que je protège avec un autre système de connection et de création d'utilisateurs.

    L'application applicative avec possibilités de création de comptes d'utilisateurs (stockés sur mysql), agit comme un proxy à la base de données postgresql, l'utilisateur modifie cette base de données avec Leaflet draw (applicatif) grâce aux pages create_point.php, etc... du dossier crud/dataservice.

    à la création d'utilisateur, l'utilisateur se voit attribuer une base de données mfy_XXX avec son numéro d'utilisateur, et dedans il ajoute autant de fichiers qu'il veut :
    matable1, matable2, qui sont declinees en matable1_linestring, matable1_polygon, matable1_point,

    Il y aurait la possibilité de créer une base de données unique pour tous les utilisateurs et faciliter mes sauvegardes, et finir avec des tables nommées USERID_TABLEID_point, et surtout empecher au systeme de peser 8 Mo pour chaque nouvel utilisateur (ce qui est enorme pour moi, chaque nouvelle base de données pese 8Mo avec Leaflet crud). Cela m'empecherait cependant, dans le futur, de proposer un accès aux utilisateurs à sa base de donnée personnelle en se connectant à Postgresql par d'autres logiciels que le mien, (photo ci-contre) c'est un choix à faire.

    Nom : screen63.jpg
Affichages : 130
Taille : 42,6 Ko

    après avoir tenté de securiser contre les injections, j'ai encore du mal à comprendre les différences entre $_GET et $_POST en ajax, dans mon code en ce moment current_file est incompris

  11. #11
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 667
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 667
    Par défaut
    Citation Envoyé par vincedchart Voir le message
    dans le futur, proposer un accès aux utilisateurs à sa base de donnée personnelle en se connectant à Postgresql par d'autres logiciels que le mien
    votre système va avoir comme 1re fonctionnalité globale de permettre à un utilisateur de saisir ces données géographique sur une carte.
    mais là, faire une base par utilisateur pour un accès par d'autres logiciels est une autre fonctionnalité très différente de la 1re. cette 2e fonctionnalité peut même interférer avec la 1re puisqu'un logiciel extérieur peut modifier les tables utilisées par leaflet crud.

    est ce que des utilisateurs vous ont expressément demandé d'avoir une base individuelle ou alors c'est ce que vous aimeriez leur proposer ?

  12. #12
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut
    Oui, effectivement il peut y avoir interference sur beaucoup d'élements dont les colonnes des bases de données.

    C'est quelque chose que je prévois mais pas tout de suite, ce n'est la demande de personne, ca sera un service en plus

  13. #13
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut
    Je suis encore bloqué. J'ai concatené directement dans le javascript, pas de changement. et pas d'error log

    Code javascript : 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
    promisePoint.then(function(data) {
            pointObjects.addData(data);
                  objectsGroup.addLayer(pointObjects);
        });
        var current_filenow = current_file + '_linestring';
        console.log(current_filenow); // a donné normandie_linestring
        var promiseLinestring = $.ajax({
            url: "../crud/dataservice/read_linestring.php",
            method: "GET",
            dataType: "json",
            data: {
                command: "LINESTRING",
                current_filepost: current_filenow
            },
            xhrFields: {
                withCredentials: true
            },
            username: null,
            password: null
        });

    php mis à jour. si je remplace directement :current_file par normandie_linestring pour tester, ca marche............. alors je ne comprends pas.

    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
    <?php
    include ("dbconfig.php");
    if(!isset($_SESSION)) {    session_start();  };
    error_reporting(E_ALL);
    ini_set("display_errors", 1);
    header("Access-Control-Allow-Origin: *");
     
    $objectfile = $_GET['current_filepost'];
     
    $geojson = array(
    	 'type'      => 'FeatureCollection',
    	 'features'  => array()
    );
    try {
    	$dbcon = new PDO("pgsql:host=".$dbconfig['_pgsql_db_host_'].";port=".$dbconfig['_pgsql_db_port_'].";dbname=mfy_26;user=".$dbconfig['_pgsql_db_user_'].";password=".$dbconfig['_pgsql_db_pass_']."");
    	$dbcon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    	$stmt = $dbcon->prepare("SELECT gid, name, cat, comment, description, public.ST_AsGeoJSON(public.ST_Transform((geom),4326),6) AS geojson FROM :current_file");
    	//$stmt->bindValue(":current_file", $objectfile, PDO::PARAM_STR); //tentative1
    	//$stmt->bindParam("s", $objectfile); //tentative2 en remplacant :current_file par ?
     
    	if($stmt->execute(array( //tentative3
    		':current_file' => $objectfile))){
    		$id_count = 0;
    		while($rowset = $stmt->fetch(PDO::FETCH_ASSOC)){
    			$properties = $rowset;
    			unset($properties['geojson']);
    			unset($properties['geom']);
    				$feature = array(
    						 'type' => 'Feature',
    						 'id' => $id_count,
    						 'properties' => $properties,
    						 'geometry' => json_decode($rowset['geojson'], true)
    				);
    			array_push($geojson['features'], $feature);
    			$id_count++;
    		}
    		header('Content-Type: application/json');
    		echo json_encode($geojson, JSON_NUMERIC_CHECK);
    		$dbcon = null;
    		exit;
    	} else {
    		header('Content-Type: application/json');
    		echo json_encode($geojson, JSON_NUMERIC_CHECK);
    		$dbcon = null;
    		exit;
    	}
    } catch (PDOException $e) {
    	header('Content-Type: application/json');
    	echo json_encode($geojson, JSON_NUMERIC_CHECK);
    	$dbcon = null;
    	exit;
    }
    ?>

  14. #14
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut
    Ce probleme de "binding values est encore la. le code suivant fonctionne mais pas si :
    1- on change $stmt en
    "SELECT gid, name, cat, comment, description, public.ST_AsGeoJSON(public.ST_Transform((geom),4326),6) AS geojson FROM :currentfile"
    2- ajouter la commande bind pour le prepared statements
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $stmt->bindValue(":currentfile", $objectfile, PDO::PARAM_STR);

    Je ne comprends pas pourquoi le bindvalue refuse de prendre en compte ce qu'il y a dans $_get
    ----
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $objectfile = $_GET['current_filepost'];
    $geojson = array(
    'type' => 'FeatureCollection',
    'features' => array()
    );
    try {
    $dbcon = new PDO("pgsql:host=".$dbconfig['_pgsql_db_host_'].";port=".$dbconfig['_pgsql_db_port_'].";dbname=mfy_26;user=".$dbconfig['_pgsql_db_user_'].";password=".$dbconfig['_pgsql_db_pass_']."");
    $dbcon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $dbcon->prepare("SELECT gid, name, cat, comment, description, public.ST_AsGeoJSON(public.ST_Transform((geom),4326),6) AS geojson FROM" . $_GET['current_filepost']);
    $stmt->bindValue(":currentfile", $objectfile, PDO::PARAM_STR);
    $stmt->execute();

  15. #15
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 322
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 322
    Billets dans le blog
    17
    Par défaut
    SELECT gid, name, cat, comment, description, public.ST_AsGeoJSON(public.ST_Transform((geom),4326),6) AS geojson
    FROM :currentfile
    Je te l'ai déjà dit, on ne peut pas utiliser les requêtes préparées avec des noms d'objets paramétrés

    C'est comme si tu faisais :

    SELECT ...
    FROM 'ta_table'
    ... et c'est un SQL invalide.

    Si tu persistes dans cette voie alors il faudra faire :

    SELECT ...
    FROM {$ta_table}
    En prenant soin manuellement que $ta_table ne contienne que des caractères valides.

  16. #16
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut
    Bonjour,

    'noms d'objets parametrés", ca veut dire modifiés en php?

    Pour comprendre, est-ce que cette page de Leaflet Crud (create_linestring) utilise des noms d'objets paramètrés ou des requêtes préparées?

    mon code a évolué depuis mon premier message, le code est désormais très proche de cet exemple de leaflet crud. mais celui-ci marche, pas le mien.
    mon paramétrage se fait désormais en amont, en javascript, avant le PHP, mon URL paramétré étant :

    site.com/pages/read_linestring.php?current_file=normandie_linestring

    Mon but est seulement de sécuriser ce $_get de current_file=normandie_linestring contre les injections SQL, avec tous les moyens possibles.

  17. #17
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 322
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 322
    Billets dans le blog
    17
    Par défaut
    'noms d'objets parametrés", ca veut dire modifiés en php?
    Non, c'est modifié/remplacé par le serveur SQL (après quelques arrangements de PHP/PDO).

    Pour comprendre, est-ce que cette page de Leaflet Crud (create_linestring) utilise des noms d'objets paramètrés ou des requêtes préparées?
    Je ne vois que :

    $stmt = $dbcon->prepare("INSERT INTO data_linestring(notes, geom) VALUES(UPPER(:notes), ST_GeomFromText(:geometry, 4326))");
    Il s'agit d'une requête préparée,
    et les paramètres :notes et :geometry sont bien utilisés pour des valeurs SQL.

    Doc PHP de PDO::prepare() https://www.php.net/pdo.prepare :

    Note:
    Les marqueurs de paramètres peuvent représenter uniquement un littéral de données complet. Ni une partie de littéral, ni un mot clé, ni un identifiant, ni toute autre requête arbitraire ne peuvent être liés en utilisant les paramètres. Par exemple, vous ne pouvez associer plusieurs valeurs à un seul marqueur de nom entrant, dans la clause IN() d'une requête SQL.
    Mon but est seulement de sécuriser ce $_get de current_file=normandie_linestring contre les injections SQL, avec tous les moyens possibles.
    Assure-toi que la variable $_GET['current_file'] est définie
    Assure-toi qu'elle ne contient que les caractères attendus, par exemple avec une regex comme /^[a-z_]+$/ (preg_match())
    Assure-toi que l'utilisateur a bien le droit de modifier cette table à ce moment précis (autrement c'est la catastrophe)
    Et place la variable ainsi validée directement dans le SQL, sans passer par un paramètre SQL
    C'est très moche (au niveau modèle de bdd, et au niveau applicatif/sécurité, avec un nom de table qui se trimballe dans une URL), mais ça répondra à ton besoin immédiat

  18. #18
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut
    Merci de la clarification.

    j'ai activé le logging de Postgresql pour lire les requêtes qui y sont faites, et j'ai plus d'info sur mon problème.
    cette variable $_get est bien définie, mais elle est mise entre guillemets simples : postgresql refuse donc de la traiter pour lire un nom de table.

    2023-08-03 16:55:24.103 CEST [111658] LOG: statement: DEALLOCATE pdo_stmt_00000001
    2023-08-03 16:55:24.111 CEST [111659] ERROR: syntax error at or near "'ukir_linestring'" at character 118
    2023-08-03 16:55:24.111 CEST [111659] STATEMENT: SELECT gid, name, cat, comment, description, public.ST_AsGeoJSON(public.ST_Transform((geom),4326),6) AS geojson FROM 'ukir_linestring'
    2023-08-03 16:55:24.117 CEST [111660] ERROR: syntax error at or near "'ukir_linestring'" at character 118
    2023-08-03 16:55:24.117 CEST [111660] STATEMENT: SELECT gid, name, cat, comment, description, public.ST_AsGeoJSON(public.ST_Transform((geom),4326),6) AS geojson FROM 'ukir_linestring'
    L'idée que j'ai maintenant, c'est que c'est toute mon architecture de base de données qui est à revoir pour cet appel à FROM ne se fasse plus par guillemets simples. Il me faudrait modifier du postgresql, du php, du javascript...

    Il faut peut etre que :
    • le nom du tableau soit formé sur un identifiant en chiffres 34_linestring, 34_point, 34_polygon.
      (et dans le futur sur USERIDNUMBER_34_point si je crée ma superbase de données plus tard),
    • qu'il y ait d'abord une recherche preparee dans l'index, d'un "select id from index where name = ?" avec $current_file en preparé mais les guillemets simples seraient acceptés.. je pense ?
    • que cet id selectionné, en chiffres, ne soit plus preparé puisque l'utilisateur n'a pas de controle sur l'identifiant en chiffres pour la requête finale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    "SELECT gid, name, cat, comment, description, public.ST_AsGeoJSON(public.ST_Transform((geom),4326),6)
    AS geojson FROM ". $tableid. "_linestring"
    donc j'essaye ça..

  19. #19
    Membre confirmé
    Homme Profil pro
    Architecte sys d'info géographique
    Inscrit en
    Juin 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Architecte sys d'info géographique
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2011
    Messages : 64
    Par défaut
    j'ai finalement décidé de créer une seule base de données pour tout le monde. maintenant quand je cherche à autoriser a ajouter une ligne à la table d'index de l'utilisateur

    (public.26_index dans ce cas)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $sqlX1 = "INSERT INTO public.".$_SESSION['user_id']."_index(name,cat) VALUES (?,'private')";
    $stmt=$dbcon->prepare($sqlX1);
    $stmt->execute(array($_GET['newtable']));
    j'ai maintenant cette erreur ... que je ne comprends pas trop

    [error] 589#0: *339239 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught PDOException: SQLSTATE[42601]: Syntax error: 7 ERROR: trailing junk after numeric literal at or near ".26_"
    LINE 1: INSERT INTO public.26_index(name,cat) VALUES ('test9','priva...
    ^ in /usr/share/nginx/html/crud/dataservice/create_tables.php:14

  20. #20
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 667
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 667
    Par défaut
    Citation Envoyé par vincedchart Voir le message
    j'ai finalement décidé de créer une seule base de données pour tout le monde.
    je suis de retour après avoir loupé 2 jours de discussion mais c'est ce que j'allais vous conseiller.
    comme je le disais plus haut, votre idée de donner accès la base est très éloignée de la fonctionnalité de saisie des données géométriques. et donc vous étiez parti sur cette architecture originale alors qu'il y a peut être seulement 1 personne sur 100 qui aurait utilisé cet accès à la base.
    et comme vous aviez une architecture très originale, vous êtes tombés sur des problème de sécurité auxquels peu de membres du forum ont été confrontés.

    le fait de mettre tous les utilisateurs dans la même table n’empêcheras pas de donner un accès direct au données aux utilisateur. cela se fait généralement par un url spécifique qu'on appelle API. par exemple adresse "serveur/admin/edition_point" va afficher le formulaire en html de saisie d'un point. et les logiciels extérieurs utiliseront l'url "serveur/api/edition_point". le logiciel enverra une requête http post et l'url répondra avec des informations en json.

    en ce qui concerne votre nouvelle architecture, je vous conseille de commencer une nouvelle discussion puisque tout ce qui est au dessus ne pose maintenant plus de souci.

Discussions similaires

  1. Récupération des valeurs d'input dans iframe par $_POST
    Par corentinparent dans le forum Général Conception Web
    Réponses: 0
    Dernier message: 26/11/2010, 18h43
  2. Perte des valeurs de $_POST avec onsubmit
    Par tisstt dans le forum Langage
    Réponses: 6
    Dernier message: 20/06/2008, 11h49
  3. Mauvaise récupération des valeurs avec $_POST
    Par Trebor_ dans le forum Langage
    Réponses: 2
    Dernier message: 02/03/2008, 10h33
  4. Réponses: 1
    Dernier message: 25/04/2007, 16h23

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