2011-07-17 106 views
1

我有以下查詢MySQL查詢神奇地抓住數值

SELECT * FROM (`user_profiles`) WHERE `user_id` = $user_id LIMIT 1 

$user_id是一個URI段。例如$user_id = 64會產生

SELECT * FROM (`user_profiles`) WHERE `user_id` = '64' LIMIT 1 

如果我將字母字符添加到用戶ID,例如http://www.mysite.com/profile/64kjdsg

我得到:

SELECT * FROM (`user_profiles`) WHERE `user_id` = '64kjdsg' LIMIT 1 

仍然返回正確的數據雖然沒有用戶ID等於64kjdsg。我的表中的用戶ID列是int(11)。該查詢似乎自動從64kjdsg獲取數值,並與數據庫表中的值匹配。這是我不知道的MYSQL函數嗎?

這是怎麼發生的?我使用Codeigniter框架查詢,如果這使螞蟻的差異。

UPDATE:發現了類似的問題MySQL integer comparison ignores trailing alpha characters

+1

如果你扔在周圍查詢的用戶ID的報價,我相信它最初被視爲文本。如果你刪除了引號,你應該在非數字輸入時得到一個mysql錯誤 – MoarCodePlz

+2

這不是真正的代碼,是嗎?在MySQL中,反向標記用於表名或列名,而不是字符串。 –

+0

@ÁlvaroG. Vicario,哎呀我的錯誤,我糾正了代碼。它在腳本中沒有反撥號。 – CyberJunkie

回答

2

當你在比較數字列,MySQL的蒙上你的字符串到數字(所以從第一個非數字字符的次數消除一切)。這是它的default behavior

mysql> select '23andthensome' + 4; 
+---------------------+ 
| '23andthensome' + 4 | 
+---------------------+ 
|     27 | 
+---------------------+ 
1 row in set, 1 warning (0.02 sec) 

mysql> show warnings; 
+---------+------+---------------------------------------------------+ 
| Level | Code | Message           | 
+---------+------+---------------------------------------------------+ 
| Warning | 1292 | Truncated incorrect DOUBLE value: '23andthensome' | 
+---------+------+---------------------------------------------------+ 
1 row in set (0.02 sec 

所以,讓更合適的查詢,事先請檢查是否東西是不是數字(filter_var(FILTER_VALIDATE_INT,$id);),只有使用它的時候它是什麼,然後:不要把它作爲一個字符串到MySQL:如果您想比較號碼,請發送不應被引用的號碼。

或者,你可以讓MySQL的做的工作,但它似乎是一種浪費:

mysql> select 23 = '23andthensome'; 
+----------------------+ 
| 23 = '23andthensome' | 
+----------------------+ 
|     1 | 
+----------------------+ 
1 row in set, 1 warning (0.00 sec) 
mysql> select cast(23 as CHAR) = '23andthensome'; 
+-------------------------------------+ 
| cast(23 as CHAR) = '23andthensome' | 
+-------------------------------------+ 
|         0 | 
+-------------------------------------+ 
1 row in set (0.02 sec) 
+0

感謝您的出色插畫! – CyberJunkie

1

入住你的腳本urlsegment整數。您可以使用ctype_digit來執行此操作。如果不是,請不要觸摸你的分貝。說 「沒有這樣的用戶」

0

這個安全漏洞 但是,如果

$user_id = 5; 

結果是

SELECT * FROM (`user_profiles`) WHERE `user_id` = 5 LIMIT 1 

SELECT * FROM (`user_profiles`) WHERE `user_id` = `5` LIMIT 1 

嘗試使用intval()

$user_id = intval($user_id); 
1

看看這個:http://ideone.com/khpEv,它被稱爲類型雜耍。如果'64kjdsg'字符串將被轉換爲整數(64),因爲user_id是INT,否則會產生語法錯誤。

PHP例子:

<?php 
echo (int) '64kjdsg'; // 64 
?> 
+0

謝謝! +1樣品 – CyberJunkie