我在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注入破解我的应用程序。我的其他一些类似的查询应用到这一个。请各位帮助我。
答案 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);
}
}
?>