2014-04-23 36 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