sécurisé - sécuriser formulaire php




Filtrer la requête MYSQL avec les options de formulaire (2)

J'ai un formulaire avec plusieurs entrées qui sont mes filtres. C'est mon code (pas tout, juste la partie que je veux corriger):

$req_resumo = '';
$req_status = '';
$req_usuario = '';
$n_req = 0;
$parametros = "";

// Checks which fields are filled and increases the number of filters for future usage
if (isset($_POST['usuario']) && $_POST['usuario'] != "") {
    $req_usuario = $_POST['usuario'];
    $n_req++;
}

if (isset($_POST['resumo']) && $_POST['resumo'] != "") {
    $req_resumo = $_POST['resumo'];
    $n_req++;
}

if (isset($_POST['status']) && $_POST['status'] != "") {
    $req_status = $_POST['status'];
    $n_req++;
}

// Then (there is some code between these parts)
if ($n_req > 0 && $funcao != 'usuario') $parametros.= " where ";
if ($req_usuario != "") {
    $parametros.= " usuario = '$req_usuario' ";
    if ($n_req > 1) $parametros.= " and ";
}

if ($req_resumo != "") {
    $parametros.= " resumo = '$req_resumo' ";
    if ($n_req > 1 && ($req_status != "") || ($req_data_inicial != "")) $parametros.= " and ";
}

if ($req_status != "") {
    $parametros.= " status = '$req_status' ";
}

// This will create the query and add the parameters string at the end.
$tot = mysqli_query($con, "SELECT * FROM solicitacoes $parametros");

Ce code a l'air moche, et même pour moi (begginer), ça ne se sent pas bien, ça ne ressemble pas à la façon de coder.

Alors, y a-t-il une meilleure façon de construire ce code?


Essayez ceci. De mes tests localement (sans DB) regardé à droite.

$n_req = 0;
$_POST['usuario'] = 'test';
$_POST['resumo'] = 'test2';
$_POST['status'] = 'test3';
if (!empty($_POST['usuario'])) {
$req_usuario = $_POST['usuario'];
$where[] = " usuario = ? ";
$params[] = $req_usuario;
$n_req++;
}
if (!empty($_POST['resumo'])) {
$req_resumo = $_POST['resumo'];
$where[] = " resumo = ? ";
$params[] = $req_resumo;
$n_req++;
}
if (!empty($_POST['status'])) {
    $req_status = $_POST['status'];
$where[] = " status = ? ";
$params[] = $req_status;
$n_req++;
}
$sql_where = !empty($where) ? ' where ' . implode(' and ', $where) : '';
echo $sql_where;
$tot = mysqli_prepare($con, "SELECT * FROM solicitacoes $sql_where");
if(!empty($params)) {
//foreach($params as $param) {
//  mysqli_stmt_bind_param($tot, "s", $param);
    //echo $param;
//}
$params = array_merge(array($tot),
                  array(str_repeat('s', count($params))), 
                  array_values($params));
print_r($params);
call_user_func_array('mysqli_stmt_bind_param', $params);
// adapated from https://.com/questions/793471/use-one-bind-param-with-variable-number-of-input-vars and http://www.pontikis.net/blog/dynamically-bind_param-array-mysqli may need to be altered
}
echo "SELECT * FROM solicitacoes $sql_where";
mysqli_execute($tot);

Si les trois valeurs sont renseignées, votre requête doit être

SELECT * FROM solicitacoes où usuario =? et resumo =? et statut =?

Le ? sont remplis avec les valeurs par le conducteur plus tard dans le processus. Cela empêche le (s) utilisateur (s) d'ajouter du code malveillant pour manipuler le traitement SQL.

https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29
Comment puis-je empêcher l'injection SQL en PHP?

Je n'ai pas non plus vu où $funcao était défini.

Vous pouvez commenter les fonctions mysqli et décompresser les lignes d'écho pour voir ce que fait le code. C'est ainsi que j'ai confirmé que les requêtes étaient en cours de construction comme prévu.


$predicates = array();
if ($_POST['usuario'] != "") {
    $predicates[] = "usuario = '{$_POST["usuario"]}'";
}
if ($_POST['resumo'] != "") {
    $predicates[] = "resumo = '{$_POST["resumo"]}'"
}
if ($_POST['status'] != "") {
    $predicates[] = "status = '{$_POST["status"]}'"
}
if (count($predicates) == 0) {
    // handle case when nothing specified in POST
} else {
    $tot = mysqli_query($con, "SELECT * FROM solicitacoes WHERE "
        . implode(" and ", $predicates) );
}

Je n'ai peut-être pas toute votre logique exactement comme requis ... mais les idées sont là. Utilisez implode() pour insérer and entre les prédicats de votre clause WHERE (cela va déterminer combien sont nécessaires, le cas échéant). De plus, puisque c'est votre formulaire HTML qui envoie le POST, vous pouvez être certain qu'au moins une certaine valeur est passée pour chaque variable POST (donc isset() n'est pas requis).







select