PHP Sql注入易受攻击

时间:2013-07-26 15:11:57

标签: php mysql

我编写了下面的脚本作为我的第一个php mysql应用程序。我是自学成才,代码按预期工作。我的主机认为它可能容易受到SQL注入攻击,但无法告诉我为什么或我应该改变什么以使其更好。我确信它不是那么干净但如果有人有任何建议或见解我肯定会感激。

<form  method="post" action="search.php?go"  id="searchform">
      <?php
      $db=mysql_connect ("server",  "*", "*") or die ('I cannot connect  to the database because: ' . mysql_error());
  $mydb=mysql_select_db("*");
$category_sql="SELECT distinct category FROM Members";
$category_Options="";
$category_result=mysql_query($category_sql) or die ('Error: '.mysql_error ());
while ($row=mysql_fetch_array($category_result)) {

    $category=$row["category"];
    $category_Options.="<OPTION VALUE=\"$category\">".$category.'</option>';
}
?>
   <p>
          <SELECT NAME="category"><OPTION VALUE=0>Choose<?=$category_Options?></SELECT>

   </p>
<input name="submit" "id="submit" type="submit" value="submit" />
    </form>


<?php
  if(isset($_POST['submit'])){
  if(isset($_GET['go'])){
  $category=$_POST['category'];
  $category=mysql_real_escape_string($category);
  $sql="SELECT category, company, address, city, state, zip, phone, web, addescription, image
  FROM Members
  WHERE category LIKE '$category'";
$result=mysql_query($sql);
  while($row=mysql_fetch_array($result)){
        $category2=$row["category"];
        $company=$row["company"];
        $address=$row["address"];
        $city=$row["city"];
        $state=$row["state"];
        $zip=$row["zip"];
        $phone=$row["phone"];
        $web = $row["web"];
        $addescription = $row["addescription"];
        $image = $row["image"];
  echo "<blockquote>";
  if(@file_get_contents($image))
{
  echo "<img src='".$image ."' class='image'/>\n";
}
else
{
}
  echo "<p>\n";
  echo "</br>".$category2 . "\n";
  echo "</br><b>".$company . "</b>\n";
  echo "</br>".$address . "\n";
  echo "</br>".$city . ", ".$state. " ".$zip . "\n";
  echo "</br>".$phone . "\n";
  echo "</br><a href=http://".$web .">".$web ."</a>\n";
  echo "</br>".$addescription . "\n";
  echo "</br><a href=http://www.printfriendly.com style=color:#6D9F00;text-decoration:none; class=printfriendly onclick=window.print();return false; title=Printer Friendly and PDF><img style=border:none; src=http://cdn.printfriendly.com/pf-button.gif alt=Print Friendly and PDF/></a>\n";
  echo "</p>";
  echo "</blockquote>"
  ;
 }


  }
  else{
  echo  "<p>Please select a Category</p>";
  }
  }
mysql_close($db)
?>

4 个答案:

答案 0 :(得分:3)

不推荐使用MySQL函数。使用MySQLi函数和预处理语句是防止sql注入攻击的更好方法。

$stmt = $mysqli->prepare('SELECT category, company, address, city, state, zip, phone, web, addescription, image FROM Members WHERE category LIKE ?');
$stmt->bind_param('s', $category);

答案 1 :(得分:1)

我将展示PDO连接的实现以及如何使用它进行查询。在这里! 首先,我们使用您的数据库凭据创建连接变量。我们会将此连接存储在$db

$username = "root";
$password = "";
$host = "localhost";
$dbname = "my_database";

$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');

try{
   $db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8"; $username, $password, $options);
}catch(PDOException $ex){
   die("Failed to connect: ".$ex->getMessage());
}

现在您有一个存储在$db中的PDO连接,您可以通过该连接进行查询。如果您不使用PHP 5.4,则可能需要考虑magic quotes,因此请记住这一点。

否则,像这样创建查询语句..

$query = "SELECT category, company, address, city, state, zip, phone, web, addescription, image FROM Members WHERE category LIKE :category"

之后,您希望将$_POST['category']变量(或创建该变量后的$category)中的值绑定到参数:category。这样做:

$query_params = array( ':category' => $category);

最后,既然您已经拥有了语句和参数,请使用先前创建的$db变量来准备和执行语句。

$statement = $db->prepare($query);
$result = $statement->execute($query_params);

由于我们SELECT数据可以返回多行(假设您在一个类别中有多行),我们需要考虑到这一点。抓取语句返回的行,如下所示:

$rows = $statement->fetchAll();

现在,您可以使用foreach语句引用数据库表的每个$row中的列标题。

$citiesArray = array();
foreach($rows as $row){
   if(isset($row['city'])){
       $citiesArray[] = $row['city'];
   }
}

希望有所帮助!

答案 2 :(得分:1)

请记住永不信任您的用户的黄金法则。永远不要接受任何原始用户输入并将其插入数据库,因为您可能会因安全问题而敞开大门。

您的代码似乎很好。但请注意,自PHP 5.5.0起不推荐使用MySQL,而应使用MySQLiPDO扩展来提供更高的安全性。

也许这就是你的主持人说出这样的事情的原因,但是从快速查看你的代码看起来对我来说似乎很好。

干杯。

答案 3 :(得分:0)

问题是代码中的以下部分

$sql = "SELECT category, company, address, city, state, zip,
             phone, web, addescription, image
        FROM Members
        WHERE category LIKE '$category'";
$result=mysql_query($sql);

如果从GET或POST参数中读取参数$ category,则应为escaped

$sql = "SELECT category, company, address, city, state, zip,
             phone, web, addescription, image
        FROM Members
        WHERE category LIKE '" . mysql_real_escape_string($category) . "';";

如果您这样做,该变量不能用于SQL Injection

顺便说一句(就像Matthew Johnson所说的那样),自PHP 5.5以来,程序的mysql扩展已被弃用。您最好使用MysqliPDO

OOP方式(强烈推荐)看起来像:

$pdo = new PDO($dsn, $user, $password, $options);
$statement = $pdo->prepareStatement(
    "SELECT category, company, address,
            city, state, zip, phone, web,
            addescription, image
     FROM Members
     WHERE category LIKE :category;");
$statement->bindParam(':category', $category, PDO::PARAM_STR);
$statement->execute();
$categories = $statement->fetchAll();