更新查询以对抗谷歌机器人黑客攻击

时间:2014-04-23 05:34:11

标签: php mysql sql

我在php中有一个代码,我可以访问女性产品或任何其他产品的任何其他链接。点击其中我将转到下一页并在querystring中传递产品名称。 然后在下一页我使用我的SQL查询,这将给我你在第一页点击的产品列表。我的项目中有很多查询像这样。这个查询非常容易谷歌机器人用SQL注入攻击以下是代码

<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>

上面使用的查询非常容易受到谷歌机器人黑客攻击。请指导我在这个查询中应该更改什么,以便谷歌博特不能用mysql注入破解我的应用程序。我的其他一些类似的查询应用到这一个。请各位帮助我。

1 个答案:

答案 0 :(得分: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.'

然后他们可以执行查询以从另一个表中获取数据(可能包含密码等),只需要一点耐心就可以获得正确数量的列等等。

如果你切换到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); 
    } 
} 
?>