2016-09-10 33 views
1

我最近進行的客戶端代碼審計,我發現這行代碼是進行盲SQL注入修補基於時間的SQL注入

代碼片段:

<?php 
if ($_GET['id'] != ''){ 
$groepsindeling = $_GET['id']; 
} else { 
$groepsindeling = $_GET['group']; 
} 
breadcrumb($groepsindeling); 
?> 

<?php 
$groep = "SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '$_GET[id]' ORDER BY `naamt1` ASC"; 
$groepres = mysql_query($groep); 
while ($groeprij = mysql_fetch_array($groepres)){ 
?> 

我立刻修補它通過使用mysqli_real_escape_string()函數。

新代碼:

<?php 
if ($_GET['id'] != ''){ 

$groepsindeling = mysqli_real_escape_string($_GET['id']); 

settype($groepsindeling, "integer"); 

} 
else { 
$groepsindeling = mysqli_real_escape_string($_GET['group']); 
} 
breadcrumb($groepsindeling); 
?> 

<?php 
$groep = "SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '$_GET[id]' ORDER BY `naamt1` ASC"; 
$groepres = mysql_query($groep); 
while ($groeprij = mysql_fetch_array($groepres)){ 
?> 

我沒有進一步的測試,看看代碼會工作,它的工作對基於SQL盲注布爾,但它似乎是基於SQL盲註失敗的時間仍然是適用於此。

所有的建議表示讚賞。

+0

您仍然在查詢中使用非轉義$ _GET ['id']。 –

+0

1.你在混合mysql和mysli apis。 2.你不應該再使用mysql api了。它在幾年前被棄用,並在php v7中被刪除。 3.簡單的轉義對於所有類型的sql注入是不夠的。要麼使用參數化查詢(在mysql api中不可用,只能在mysqli或pdo中使用),或者必須加強轉義代碼。 – Shadow

+0

@CapitalC但我仍然可以使用查詢內的函數嗎? – epidrollic

回答

1

正如上面所說的,你用$ _GET [ '身份證']在你的查詢,這意味着人們仍然可以SQL注入的查詢字符串:

$groep = "SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '$_GET[id]' ORDER BY `naamt1` ASC"; 

儘量做到:

$groep = "SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '{$groepsindeling}' ORDER BY `naamt1` ASC"; 

然後你使用你使用real_escape_string的「$ groepsindeling」變量。

你也應該閱讀http://php.net/manual/en/mysqli.real-escape-string.php - 因爲它說,當你使用「mysqli_real_escape_string」你還需要設置的方法和mysqli對象:

string mysqli_real_escape_string (mysqli $link , string $escapestr) 

此外,你應該保持到庫MySQLi或MySQL (不要推薦這個)。

+0

非常感謝,現在已經解決了!幫助!! – epidrollic

+0

@epidrollic - 原始代碼有缺陷,你意識到這個對嗎?在原始代碼中'$ _GET ['group'];'從未在查詢中使用。通過更新您將它放入查詢中,查詢可能是原本想要的,也可能不是。換句話說,假設'$ groepsindeling'='$ _GET [id]'不正確。應該使用一個新的變量。 – ArtisticPhoenix

1

正如其他人指出的那樣,您在查詢中仍然存在$_GET['id'],但$groepsindeling可能與get var無關,嚴格來說。基本上就是你說的是這個

$groepsindeling = $_GET['id'] or $_GET['group']; 

這裏Represnted:

if ($_GET['id'] != ''){ 
    $groepsindeling = $_GET['id']; 
} else { 
    $groepsindeling = $_GET['group']; 
} 

這是不是在原來的查詢表示。

"SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '$_GET[id]' ORDER BY `naamt1` ASC"; 

查詢是嚴格使用$_GET['id'],和我沒有看到$_GET['group']在那裏。然後,這留下兩個選擇,

  • 原代碼是有缺陷的
  • 原代碼是正確的(在這種情況下的$ id應該是一個新的變量)

所以像這樣

$id = mysqli_real_escape_string($_GET['id']); 

"SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '$id' ORDER BY `naamt1` ASC"; 

如果沒有看到這個頁面的整個代碼,就不可能知道這個$groepsindeling是否與查詢有關,或者只是在其他地方使用。我提到的另一種可能性是它們是相同的,並且原始代碼被竊聽。

所有這一切,鑑於breadcrumb($groepsindeling);我認爲它與查詢無關,並保持原樣。更改它並在查詢中包含$_GET['group']值可能會導致不可預知的行爲,特別是如果該查詢依賴於任何東西的$_GET['id'] = ''

合理。

作爲一個方面說明,在當前的PHP版本,這$_GET[id]從原來的查詢可能會拋出一個undefined constant警告,我已經看到了這個預5.3 PHP代碼之前使用....它應該是$_GET['id']。它仍然有效,因爲PHP會給它的名字的字符串表示一個未定義的常量。 (只是一種方式來告訴代碼幾歲:-P)

而最後一個音符是您正在使用mysql_querymysqli_real_escape_string使i在那裏有一定的意義,或在此mysql_query它的不足。 mysql_*函數已被棄用,如果我記得從PHP 7開始刪除,這意味着此代碼不是PHP 5x以後的未來證明。我不確定mysql_real_escape_stringmysqli_real_escape_string之間是否有任何顯着差異