2014-04-23 35 views
0

我有一个PHP代码,其中我在女性产品或任何其他产品的任何其他链接clikcing。点击哪个我去下一页,并在querystring中传递产品名称。 然后在下一页即时通讯使用我的sql查询,这将给我在第一页上点击的产品列表。在我的项目中有很多像这样的查询。这个查询是很容易谷歌机器人黑客与SQL injection.Following是代码更新查询来打击谷歌机器人黑客入侵

<html> 
<head> 
</head> 
<body> 
<ul id="list"> 
      <li><h3><a href="search.php?name=women-top">tops</a></h3></li> 
      <li><h3><a href="#">suits</a></h3></li> 
      <li><h3><a href="#">jeans</a></h3></li> 
      <li><h3><a href="search.php?name=women">more</a></h3></li> 
      </ul> 
</body> 
</html 

的search.php

<?php 
$mysqli = new mysqli('localhost', 'root', '', 'shop'); 

    if(mysqli_connect_errno()) { 
     echo "Connection Failed: " . mysqli_connect_errno(); 
     } 
?> 
<html> 
<head> 
</head> 
<body> 
<?php 
session_start(); 
$lcSearchVal=$_GET['name']; 
//echo "hi"; 
$lcSearcharr=explode("-",$lcSearchVal); 
$result=count($lcSearchVal); 
//echo $result; 



$parts = array(); 
$parts1=array(); 
foreach($lcSearcharr as $lcSearchWord){ 
    $parts[] = '`PNAME` LIKE "%'.mysql_real_escape_string($lcSearchWord).'%"'; 
    $parts1[] = '`TAGS` LIKE "%'.$lcSearchWord.'%"'; 
    //$parts[] = '`CATEGORY` LIKE "%'.$lcSearchWord.'%"'; 
} 

$stmt = $mysqli->prepare('SELECT * FROM xml where'.'PNAME LIKE ?'); 
var_dump($stmt); 
$parts='%women%'; 
$stmt->bind_param('s',$parts); 

$list=array(); 
if ($stmt->execute()) { 
    while ($row = $stmt->fetch()) { 
    $list[]=$row; 
    } 
} 


    $stmt->close(); 

    $mysqli->close(); 
foreach($list as $array) 
{ 
?> 
      <div class="image"> 
<img src="<?php echo $array['IMAGEURL']?>" width="200px" height="200px"/></a> 
<?php 
} 
?> 
</div> 
</body> 
</html> 

以上使用查询IM是很容易谷歌机器人hacking.Please指导我,我应该在此查询更改,使谷歌机器人将无法破解我的应用程序与MySQL注入..在我的应用程序中有一些其他类似的查询这一个。请大家帮助我。

+0

首先,你应该停止使用'mysql_'变量的数字。它已被弃用,这意味着没有更多的支持,并在最新版本的PHP中不可用。其次,你应该使用'mysqli_'或'PDO'和**准备好的语句**。他们帮助反对SQL注入。“ –

+0

k.in的地方的MySQL,我寒use使用mysqli,ryt?和我寒also也使用这个准备的语句.... – user3545382

+0

是的,看看这个不错的[教程](http://mattbango.com/notebook/code/prepared-statements-in-php-and-mysqli /)for'mysqli_ *'with prepared statements。 –

回答

1

这是开放给SQL注入的原因是你没有逃过输入。

例如,你也行: -

$parts[] = '`PNAME` LIKE "%'.$lcSearchWord.'%"'; 

如果有人用了一个链接类似如下(忽略编码得到它的URL工作): -

search.php?name=fred%' UNION SELECT * FROM users # 

你将登陆了与SQL会是这样的: -

SELECT * FROM xml WHERE (`PNAME` LIKE "%fred%' UNION SELECT * FROM users #%")limit '.$offset.', '.$limit1.' 

那么他们可以执行一个查询得到d从另一个表(可能是一个包含密码等),只需一点耐心得到正确的列数,等等。

如果您切换到mysqli_ *,您可以使用参数化查询,但这些是当SQL本身发生变化时(就像你在这种情况下使用可变数量的LIKE语句)那样轻微的痛苦。

简单的解决方案是在SQL中使用的变量上使用mysql_real_escape_string()/ mysqli_real_escape_string()。

foreach($lcSearcharr as $lcSearchWord) 
{ 
    $parts[] = '`PNAME` LIKE "%'.mysql_real_escape_string($lcSearchWord).'%"'; 
    $parts1[] = '`TAGS` LIKE "%'.mysql_real_escape_string($lcSearchWord).'%"'; 
    //$parts[] = '`CATEGORY` LIKE "%'.mysql_real_escape_string($lcSearchWord).'%"'; 
} 

这是值得切换到mysqli_ *,如果你可以。

编辑

使用脚本mysqli_播放()和类和函数来应付参数

<?php 
session_start(); 

$mysqli = new mysqli('localhost', 'root', '', 'shop'); 

if(mysqli_connect_errno()) 
{ 
    echo "Connection Failed: " . mysqli_connect_errno(); 
} 

?> 
<html> 
<head> 
</head> 
<body> 
<?php 

if (array_key_exists('name', $_GET)) 
{ 
    $lcSearchVal = $_GET['name']; 

    $lcSearcharr = explode("-",$lcSearchVal); 
    $result = count($lcSearchVal); 

    $parts = array(); 
    foreach($lcSearcharr as $lcSearchWord){ 
     $parts[] = "%$lcSearchWord%"; 
    } 

    $bindParam = new BindParam(); 

    $parms = array(); 
    foreach($parts as $aPart) 
    { 
     $parms[] = ' PNAME LIKE ? '; 
     $bindParam->add('s', $aPart); 
    } 

    $query = 'SELECT IMAGEURL FROM xml where '.implode(' OR ', $parms); 

    $stmt = $mysqli->prepare($query); 

    if ($stmt) 
    { 

     call_user_func_array(array($stmt, "bind_param"), refValues($bindParam->get())); 

     if ($stmt->execute()) 
     { 
      while ($row = $stmt->fetch()) 
      { 
       echo '<div class="image"><img src="'.$row['IMAGEURL'].'" width="200px" height="200px"/></a>'; 
      } 
     } 
     else 
     { 
      echo $mysqli->error; 
     } 

     $stmt->close(); 

     $mysqli->close(); 
    } 
    else 
    { 
     echo $mysqli->error; 
    } 
} 
else 
{ 
?> 
<ul id="list"> 
    <li><h3><a href="search.php?name=women-top">tops</a></h3></li> 
    <li><h3><a href="#">suits</a></h3></li> 
    <li><h3><a href="#">jeans</a></h3></li> 
    <li><h3><a href="search.php?name=women">more</a></h3></li> 
</ul> 
<?php 
} 
?> 
</div> 
</body> 
</html> 

<?php 

function refValues($arr) 
{ 
    if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+ 
    { 
     $refs = array(); 
     foreach($arr as $key => $value) $refs[$key] = &$arr[$key]; 
     return $refs; 
    } 
    return $arr; 
} 

class BindParam 
{ 

    private $values = array(), $types = ''; 

    public function add($type, $value) 
    { 
     $this->values[] = $value; 
     $this->types .= $type; 
    } 

    public function get() 
    { 
     return array_merge(array($this->types), $this->values); 
    } 
} 
?> 
+0

请查看我的更新代码once.whether是一个安全的sql命令还是有问题 – user3545382

+0

看起来像是,虽然这取决于是否从用户输入中获取$ limit,$ limit1和$ offset。 – Kickstart

+0

即使删除这些变量也无效 – user3545382