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

标签 php mysql sql

我在 php 中有一个代码,我可以在其中单击女性产品或任何其他产品的任何其他链接。单击该代码后,我将转到下一页并在查询字符串中传递产品名称。 然后在下一页中,我使用我的 sql 查询,这将为我提供您在第一页上单击的产品列表。我的项目中有很多像这样的查询。这个查询很容易被 Google 机器人通过 SQL 注入(inject)进行黑客攻击.以下是代码

<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

搜索.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>

我上面使用的查询很容易受到 Google Bot 黑客攻击。请指导我应该在此查询中更改什么,以便 Google Bot 无法通过 mysql 注入(inject)攻击我的应用程序。我的应用程序中还有一些其他类似的查询应用到这个。请大家帮我解决这个问题。

最佳答案

这对 SQL 注入(inject)开放的原因是您没有转义输入。

例如,您有以下行:-

$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); 
    } 
} 
?>

关于php - 更新查询以对抗谷歌机器人黑客攻击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23235569/

相关文章:

php - 让客户端与服务器上的进程通信

PHP:一种通过循环排序并在查询后排除某些条目的方法

sql - 当我将 SQL 列更新为自身时会发生什么? -或- 简化条件更新?

sql - 数据库:流水线函数

mysql - 选择多列创建结果

php - PDO SQL 错误?错误 1140 : Mixing of GROUP columns with no GROUP columns

php - 获取单个数组中的两个类别值

php - MySQLi速度: multiple queries or one

php - 如何使用 PHP 将一组特定的用户数据从一个 MySQL 数据库移动到另一个数据库?

php - MySQL查询结果