【问题标题】:Search,filter database form make more secure [duplicate]搜索,过滤数据库表格使更安全[重复]
【发布时间】:2021-08-11 13:07:06
【问题描述】:

我有以下代码,我的问题是如何使 SQL 注入更安全。 如果可能的话,你能告诉我我做错了什么并纠正我的代码吗? 我怎样才能使它更安全地 SQL 注入,我怎样才能清理它或防止 SQL 注入的其他方法。 我不知道我该怎么做。

谢谢你的帮助

在我的 index.html 中

<form action="index.php" method="POST">
<p>Date: <input type="text" id="datepicker1"></p>
<p>Date: <input type="text" id="datepicker2" name="checkout"></p>
<select name="search" >
<option value="" disabled selected>To where</option>
<option value="hative">hative</option>
<option value="waai">waai</option>
<option value="pantai">pantai</option>
<option value="gunung">gunung</option>
<option value="passo">passo</option>
</select>
<input type="submit">
</form>

和 index.php(用于显示所有结果)

<script>
$(document).ready(function(){

    filter_data();

    function filter_data()
    {
        $('.filter_data').html('<div id="loading" style="" ></div>');
        var action = 'fetch_data';
        var minimum_price = $('#hidden_minimum_price').val();
        var maximum_price = $('#hidden_maximum_price').val();
        var brand = get_filter('brand');
           var brands = get_filter('brands');
        //var ram = get_filter('ram');
        //var storage = get_filter('storage');
        $.ajax({
            url:"fetch_data.php",
            method:"POST",
            //data:{action:action, minimum_price:minimum_price, maximum_price:maximum_price},
            data:{action:action, minimum_price:minimum_price, maximum_price:maximum_price, brand:brand,brands:brands},
            success:function(data){
                $('.filter_data').html(data);
            }
        });
    }

    function get_filter(class_name)
    {
        var filter = [];
        $('.'+class_name+':checked').each(function(){
            filter.push($(this).val());
        });
        return filter;
    }

    $('.common_selector').click(function(){
        filter_data();
    });

    $('#price_range').slider({
        range:true,
        min:0,
        max:600,
        values:[0, 600],
        step:50,
        stop:function(event, ui)
        {
            $('#price_show').html(ui.values[0] + ' - ' + ui.values[1]);
            $('#hidden_minimum_price').val(ui.values[0]);
            $('#hidden_maximum_price').val(ui.values[1]);
            filter_data();
        }
    });

});
</script>

最后是 fetch_data.php

include('database_connection.php');
if(isset($_POST["action"]))
{
 $query = "
  SELECT * FROM hotels  WHERE product_status = '1'
 ";
 if(isset($_POST["minimum_price"], $_POST["maximum_price"]) && !empty($_POST["minimum_price"]) && !empty($_POST["maximum_price"]))
 {
  $query .= "
   AND product_price BETWEEN '".$_POST["minimum_price"]."' AND '".$_POST["maximum_price"]."'  ";
 }
if(isset($_POST["brand"]))
 {   
   $brand_filter = implode("','", $_POST["brand"]);
  $query .= "  AND product_price BETWEEN '100' AND '130' ";
 }
 if(isset($_POST["brands"]))
 {   
   $brand_filter = implode("','", $_POST["brands"]);
  $query .= "  AND product_price BETWEEN '400' AND '600' ";
 }
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 $total_row = $statement->rowCount();
 $output = '';
 if($total_row > 0)
 {
  foreach($result as $row)
  {
     $output .= '
   
   <div class="col-12 col-lg-12 col-md-12 col-sm-12 col-xl-12 col-xxl-12">
        <div style="border:1px solid #ccc; border-radius:5px; padding:16px; margin-bottom:16px; height:250px;">
            <div class="col-md-4 col-sm-4">     
                <a href="'. $row['hotel_page'] .'"><img src="image/'. $row['hotel_image'] .'" width="100%" height="200px" alt="" class="img-responsive" ></a>
            </div>
            <div class="col-12 col-lg-6 col-md-6 col-sm-7 col-xl-6">
             ' . $rating_element . '
            <p align="center"><strong><a href="'. $row['hotel_page'] .'">'. $row['hotel_name'] .'</a></strong></p>
                <h4 style="text-align:center;" class="text-danger" >'. $row['product_price'] .'</h4>
            </div>
        </div>

   </div>
   ';
  }
 }
 else
 {
  $output = '<h3>No Data Found</h3>';
 }
 echo $output;
}

【问题讨论】:

  • 安德鲁,我为您的问题所做的编辑旨在改进其语法。你为什么拒绝它?
  • 对不起,只是点击错误..对不起

标签: php html mysql sql


【解决方案1】:

您正在寻找的东西称为参数化查询,PDO 完全支持它。如果你幸运的话,它已经在你的 PHP 中启用了。如果没有,那么您需要启用它(查看 php.ini 并可能安装必要的扩展)。

连接示例:

$host = '127.0.0.1';
$db   = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];
try {
     $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
     throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

取自https://phpdelusions.net/pdo

查询示例:

$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status=?');
$stmt->execute([$email, $status]);
$user = $stmt->fetch();
// or
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email AND status=:status');
$stmt->execute(['email' => $email, 'status' => $status]);
$user = $stmt->fetch();

因此,与其将变量放入表示查询的字符串中并允许执行该参数中的任何恶意代码,不如使用参数化查询并让 PDO 为您完成繁重的工作。您唯一需要应用的是查看所有代码,将硬编码的值转换为查询中的参数,并修改您的代码以使用 PDO 并传递参数,当然。

【讨论】:

  • 如何将我的代码更改为参数化查询和 PDO?
  • @andrewpuni 请看看我的回答。它包含参数化查询的示例。参数可以添加为?签名或作为:参数名称。请仔细阅读答案。例如,您有AND product_price BETWEEN '".$_POST["minimum_price"]."' AND '".$_POST["maximum_price"]."' ",您在其中传递$_POST["minimum_price"]$_POST["maximum_price"],这是不安全的。而是尝试做类似AND product_price BETWEEN ? AND ? "AND product_price BETWEEN :minimum_price AND :maximum_price "
  • @andrewpuni 并且您需要定义值,请参阅传递给 execute 方法的数组,该方法定义了 PDO 应清理的值。现在,请先尝试更简单的示例,然后再对更长的查询进行操作。你会发现这种方法很有效,如果你这样做,你未来的自己会感谢你。
  • 我想我现在明白了..我只有最后一个问题,如果我只是通过参数化它们来纠正我的所有查询,是否足以使其安全?它足够安全吗?谢谢
  • @andrewpuni 基本上是的。实际上,没有。在某些情况下,即使输入经过净化,SQL 注入仍然是可能的。例如,如果您有一个数字输入并且您的查询执行了类似 where foo = 的检查,那么如果用户将 12; delete from users; 作为数字传递,那么 SQL 注入仍然是可能的。但这是一个不同的问题。简而言之:PDO 在清理输入方面做得很好,但您仍然需要对非数字输入进行一些验证。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多