如何防止此类中的 sql 注入? [关闭]

Posted

技术标签:

【中文标题】如何防止此类中的 sql 注入? [关闭]【英文标题】:How can I prevent sql injection in this class? [closed] 【发布时间】:2014-04-07 18:56:06 【问题描述】:

我正在尝试创建一个数据库类并希望在其中包含 real_escape 字符串,但每当我这样做时,我都没有得到任何结果。请帮忙:

<!DOCTYPE html>
<head>
<title>php Classes</title>
</head>

<body>
<?php
class Database

    function Database($host, $user, $pass, $db)
        $this -> con = mysqli_connect($host, $user, $pass, $db);
    
    function runQuery($query)
        mysqli_query($this -> con, $query);
    

?>


<?php
    $database = new Database("localhost", "root", "", "website");
    $database -> runQuery("DELETE FROM subject WHERE name = 'Footer'");
?>
</body>
</html>

【问题讨论】:

仅凭这段代码是不可能的。这完全取决于如何使用此代码。如果程序只将硬编码查询传递给runQuery 方法,那么它是安全的。如果它动态构建 SQL,它很可能容易受到 SQL 注入攻击。换句话说,SQL 注入不是单个函数或类的问题,而是整个应用程序的问题。 查看准备好的语句和参数化查询 - How can I prevent SQL injection in PHP? 它将被从我到我的用户的每一个人使用 为什么不能在runQuery函数中在mysqli_query之前使用? 请放更多代码和示例 【参考方案1】:

根据您发布的代码,您不能。你的类接受一个已经组装好的查询,此时执行任何形式的清理或转义都为时已晚。

您需要通过转义用户输入的数据来防止 SQL 注入,将其组装到查询中;理想情况下,您将通过参数化查询执行最终组装。

【讨论】:

为了澄清起见,mysqli 确实支持参数化准备好的语句(并且实际上为特定于 MySQL 的它们提供了比默认 PDO 设置更好的 MySQL 原生支持,默认 PDO 设置将为 MySQL 使用模拟准备)。因此,没有理由专门从 mysqli 迁移到 PDO 来支持参数化的预处理语句。 @MikeBrant,PDO 也可以配置为使用非模拟准备。而且使用起来比mysqli容易得多,特别是对于像OP试图编写的通用类。 +1 @meager 的回答。如果用户可以提交任意 SQL 语句,则类内部没有任何保护可能。 @BillKarwin 您对通过 PDO 使用本机 MySQL 准备的能力是正确的,这只是意味着您有一个要更改的设置(这就是为什么我指出模拟准备是默认设置的原因)。我的主要观点是要注意缺乏具有参数化参数支持的准备好的语句不是选择 PDO 而不是 mysqli 的原因。该决定应该取决于其他因素(您个人对语法风格的偏好、未来需要支持多种数据库类型等)。【参考方案2】:

我建议你在这个类中使用单例模式。

class Database

   private $database;   
   static $instance;

   private $query;
   private $result;


   private function __construct($params)
   
       if($params!=null)
       
           @$this->database = mysqli_connect($params->dbSettings['dbHostName'],$params->dbSettings['dbUserName'],$params->dbSettings['dbPassword']) or die('DB Error occured.');
           $this->query="";
           $this->result=null;
           mysqli_select_db($this->database,$class->dbSettings['dbName']);
           
       else
       
           die('DB credentials not entered...');
            exit;   
       
   


   public static function GetInstance($params)
   
       if(!(self::$instance instanceof self))
       
          self::$instance = new self($params);  
                   
       return self::$instance;
   

   public function __destruct()
   
       if($this->database)
       
           mysqli_close($this->database);   
       
   

   public function ExecuteQuery($query)
                   
        $this->query=addslashes($query);
        $this->result = mysqli_query($this->database,$query);
   
   public function GetResult()
               
          if($this->result!=null)
          
                 $returnArray=array();
                 $rows = mysqli_num_rows($this->result);
                 if($rows>0)
                                   
                        while($row = mysqli_fetch_assoc($this->result))
                        
                               $returnArray[]=$row; 
                        
                 
                 return $returnArray;
          
          else
          
                 return null;
                            
               

请注意!!!。您必须过滤来自用户的所有数据。始终为每个字段使用添加斜杠方法。 mysqli 对 sql 注入也有一些保护。

【讨论】:

以上是关于如何防止此类中的 sql 注入? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

php如何防止sql注入?

如何防止SQL注入漏洞

SQL注入如何产生?如何防止?

如何防止Android中的SQL注入?

如何防止 JSP 中的 SQL 注入?

SQL Server如何防止动态sql中的sql注入