Safe Search

Started by fordhenries, Oct 18, 2022, 02:51 AM

Previous topic - Next topic

fordhenriesTopic starter

Hi for all!
I'm sorry if I'm not writing here.

There is a simple search form on website.
First I learned how to write queries, now I'm trying to make my work safe.

<?php
require_once '.config.php';
mysqli_set_charset($db"utf8");
$query=$_POST['query'];
$sql "SELECT * FROM product WHERE content = ?";
if (!empty(
$query) && trim($query) !=''){
    
$stmt mysqli_prepare($db$sql);
    
mysqli_stmt_bind_param($stmt's'$query);
 
    
$result mysqli_stmt_get_result($stmt);
// read data
while ($row mysqli_fetch_assoc($result)) {
    
// associative array with the next entry from the result
    
var_dump($row);
}
    
        if (
mb_strlen($query) < 12) {
            echo 
'<p>The search term is too short.</p>';
        } else if (
mb_strlen($query) > 12) {
            echo 
'<p>The search term is too long.</p>';
        }
if(
mysqli_num_rows($result) > 0){
    foreach(
$result as $row){
        
$str=$row['info'];/*create a variable to display results*/
        
$stra=$row['content'];/*create a variable to display results*/
        
$strm=$row['date_created'];/*create a variable to display results*/
            
echo "<p>Your ID: " htmlentities($straENT_QUOTES'UTF-8') . "</p>";
            echo 
"<p>Product: " htmlentities($strENT_QUOTES'UTF-8') . "</p>";
            echo 
"<p>Production date: " htmlentities($strmENT_QUOTES'UTF-8') . "</p>";
    }
}
else{
        echo 
"<p>No results were found for your search.</p> <p><b>Please try again by clicking the button below.</b></p>";
    }
    
mysqli_free_result($result);
}
else{
    echo 
"<p>An empty search term has been set.</p> <p><b>Try again by clicking the button below.</b></p>";
}
mysqli_close($db);
?>

The user scores the request, but sees "Nothing was found for your request.". And the found result should be displayed.
What am I doing wrong?
I will be grateful for your advices.
  •  

expointer

You have not mastered Post-Redirect-Get, although I have described this method to you in detail in relation to error handling. The output of the results can be done in much the same way:
POST /search[...]
query: search-code -POST-parameter
and, if successful, redirection for the request
GET /search/search-code

Yes, in fact, the request to the database will be executed twice, as well as an HTTP request, but this is a generalized method that is well suited for different cases, because during search queries, different encoding of keys often occurs or simply their substitution with certain codes or identifiers. If you don't want to generalize, do as you wrote above:
GET /search?query=search-code

By the way, you don't have to make a search query to the database twice.
When processing a POST request, you can simply check the text with keys for compliance with certain criteria (for example, check the same length), and immediately make a redirect if everything is in order. And already in response to a GET request, execute a query to the database. Moreover, in this case, it is better to perform the same preliminary checks before requesting the database.

As for security, in addition to using prepare/execute, do not forget to handle errors returned by mysqli functions (methods). The prepare, bind_param, execute, and get_result methods can return errors.
Even set_charset can.

By the way, where do you have execute()?
Usually they make special functions so that they don't write prepare, etc. every time, and separate ones for the SELECT query and INSERT, UPDATE, etc. requests, usually do not use the return value to indicate an error, but generate the corresponding exception.
  •