2013-03-22 71 views
2

我有下面的代碼在我的PHP文件中的一個從數據庫提取數據:MySQL的注射用LIKE操作

$products = $this->db->get_rows('SELECT * from products WHERE shop_id='.$_SESSION['shop_id'].'AND tags,title,text LIKE \'%'.$_POST['search'].'%\''); 

是否有問題?我的意思是LIKE操作符可以被注入?

編輯

請提供這樣

+0

是的,它可以注射。 SQL中的 – Randy 2013-03-22 21:12:44

+6

**可以注入任何**。你是開放的。只是因爲它在「喜歡」部分意味着什麼。沒有什麼不可思議的,因爲它使它無懈可擊。 – 2013-03-22 21:12:46

+0

在SQL注入攻擊期間,它不是運營商正在利用的,它是參數。使用準備好的語句,並刪除這個攻擊選項。 – bernie 2013-03-22 21:13:14

回答

5

任何操作員都可以無約束地注入。

$_POST['search'] = "1%'; DROP TABLE myTable LIKE '%"; 

會做出how to bind parameters

.... AND tags,title,text LIKE '%1%'; DROP TABLE myTable LIKE '%%' 

閱讀。

2

當然,這可以被注入注入的例子,你需要淨化你的輸入。現在,您正在使用原始數據並將其插入到SQL語句中。

你應該通過某種數據消毒,一些像mysql_real_escape_string或類似

,或者至少準備的語句運行POST數據。讓服務器端代碼爲您完成工作。

1

永遠,永遠,就像使用數據庫查詢,不構建具有變量的字符串,並將其用於數據庫活動。

構造將在後面作準備並通過將變量到字符串,使它們不表現得像「命令」,而是「值」執行時,一個字符串。

你可以這樣說:現在

$query = "SELECT * from products WHERE shop_id = :shopId;"; // An example, you can finish the rest on your own. 

,您可以準備語句(我推薦使用PDO此)。

$statement = $db->prepare($query); // Prepare the query. 

現在可以執行變量到準備好的查詢:

$statement->execute(array(
    ':shopId' => $_SESSION['shop_id'] 
)); 

如果要插入或更新,那麼你會想要做的:

$success = $statement->execute(array(
    ':shopId' => $_SESSION['shop_id'] 
)); 

,其存儲布爾在$成功,或者你可以從結果獲取的值,如果你選擇:

$statement->execute(array(
    ':shopId' => $_SESSION['shop_id'] 
)); 
$result = $statement->fetch(PDO::FETCH_ASSOC); 
if($result) 
{ 
    // You can access $result['userId'] or other columns; 
} 

請注意,您應該居然提出,是一個函數,並傳遞$ shopId到函數,而不是會議本身,並檢查是否會確實存在。

我建議谷歌搜索關於如何使用PDO,還是先看看對我的一個例子:How to write update query using some {$variable} with example

1

這是非常糟糕的。將變量拉入SQL語句中而不進行清理或檢查它們是獲得pwnd的好方法。人們可以注入代碼中有幾件事。另一種注意方法,1 = 1總是返回true。

$products = $this->db->get_rows('SELECT * from products WHERE shop_id='.$_SESSION['shop_id'].'AND tags,title,text LIKE \'%'.$_POST['search'].'%\''); 

//This example expects no result from the table initially so we would blind attack the DB to pull the admin record. 
$_POST['search'] = "-1\'; union all select * from users limit 1;"; 

有人打電話把數據庫中的頂級帳戶(如管理員)拉起來。

$user_id = $this->db->get_rows('SELECT * from users WHERE email="'.$_POST['email'].'" and password="'.$_POST['password'].'"'); 

//This always returns true so now I'm the admin again 
$_POST['password'] = "x\' or 1=1 limit 1"; 

你也要小心你在屏幕上打印什麼。

$user_id = $this->db->get_rows('SELECT * from users WHERE email="'.$_POST['email'].'" and password="'.$_POST['password'].'"'); 

你迴音,說的消息「沒有用戶名,$ _ POST存在[‘電子郵件’]」可以用別的東西代替。

$_POST['email']="; 

$fp = fopen('index.php', 'w'); 
fwrite($fp, \"header('Location: http://badwebsite.com;');\"; 
fclose($fp);"; 

的index.php可能現在人們到不同的網站完全在那裏被感染的頁面存在或網站上的病毒感染的網頁。

如果你正在檢查標識做這樣的事情:

if(preg_match('!^[0-9]$!',$_POST['id'])){ 
    $id = $_POST['id']; 
} else { 
    //flush 
} 

或計數的可能的記錄數......如果你只期待一個,你會得到所有的記錄在數據庫中,然後這是一次注射嘗試。

if(is_numeric($_POST['id'])){ 
    $id = $_POST['id']; 
    $count = mysql_result(mysql_query("select count(*) from users where id='$id''),0); 
}