2010-07-02 37 views
1

將我的表單字段命名爲與我的列名稱相同是不好的?我的意思是人們真的這樣做:命名郵局密鑰的動態SQL查詢

<?php 
$id = intval($_POST['user_unique_key']); 
$name = mysql_real_escape_string($_POST['name_of_user']); 
$email = mysql_real_escape_string($_POST['user_mail_thing']); 
$address = mysql_real_escape_string($_POST['user_place_of_living']); 
//.... 
$sql = "INSERT INTO `users`('id','name','email','address') VALUES($id,$name,$email,$address)" 
?> 

另外請注意,上述數據驗證是可怕的!我永遠不會使用它。

<a href="http://forums.devnetwork.net/viewtopic.php?f=50&t=118175">My Data Validation</a> 

我應該使用表格前綴:'secret_prefix_'嗎?

我不太喜歡的最終解決方案是我可以使用雙向散列來散列字段名稱。因此,有輸入的名稱是

<?php echo $field_name = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $key, MCRYPT_MODE_ECB, $iv));?> 

,然後一旦它被張貼

<?php 
    foreach($_POST as $name=> $value) 
    { 
    $input[base64_decode(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $name, MCRYPT_MODE_ECB, $iv))] = $value; 
    }?> 

回答

1

將我的表單字段命名爲 與我的列名相同是不好的?

簡短的回答是並不總是,改變列/數據庫/表的名稱可以使應用程序更耐如果你的數據庫配置正確的攻擊。默認情況下,如果攻擊者有sql注入,攻擊者可以獲取這些數據,因爲如果你給他的話,這並不重要。

如果你想那麼掩蓋這些名字,你還必須取消獲得的INFORMATION_SCHEMA數據庫:

REVOKE SELECT ON INFORMATION_SCHEMA.* TO mysql_app_user

這裏是爲什麼原因:

一種常見的SQL注入攻擊是從另一個表中選擇多汁的數據。在MySQL中,您不能像「插入...」;選擇* from ...; grant ...)那樣「堆疊quires」。所以你必須使用「聯合選擇」。

例如:

mysql_query("select path,type from images where id=".$_GET[id]); 

相應的利用如下:

http://localhost/sql_inj.php?id=0 union select username,password from users where id=1 

在這種情況下,第一選擇語句將是空的,沒有主密鑰將是零。第二條select語句將從同一個數據庫中的user表中選擇usernamepassword,這將抓取1的主鍵,其中99%的時間爲管理員。爲了解決這個問題,您需要知道表格的名稱和您需要的列。

那麼,在mysql中有information_schema數據庫絞車提供了這個數據。因此,如果列和數據庫名稱被遮蔽,則仍可通過以下方式獲得它們:

http://localhost/sql_inj.php?id=0 union select COLUMN_NAME,"junk" from FROM INFORMATION_SCHEMA.COLUMNS where COLUMN_NAME like "%user" 

此查詢將擊敗任何安全前綴。但是,這種相同的攻擊可用於獲取ALL列,MySQL數據庫中的數據庫和表。如果您撤消對Web應用程序的mysql用戶帳戶的選擇權,那麼他不能這樣做。您還應該撤消FILE的權限,因爲這些權限可用於上傳後門或讀取配置文件。

0

如果在服務器端的清理/驗證碼是強解碼字段名,那麼它並沒有真正問題是你的表單字段與表名相同/接近。

不要浪費時間試圖混淆它,如果您對自己的乾淨方法有信心,請使用常規字段名稱。

+0

安全層,你應該計劃在失敗之後,爲什麼密碼存儲爲一個散列。 – rook 2010-07-02 17:55:46

+0

我同意層中的安全性,但我的觀點仍然支持:) – Bartek 2010-07-02 18:59:22

0

首先,我不會依賴混淆表單字段名稱作爲您的Web安全解決方案。這是更好的使用多種方法的安全性:

  1. 過濾(如您使用的intval()
  2. 驗證
  3. 逃逸(如果你插值內容轉換成SQL字符串)使用參數
  4. 準備好的查詢(你需要使用ext/mysqli或ext/pdo_mysql)

這就是說,混淆字段名稱不會傷害。我不會去顯示哈希列名的極端例子。這是不必要的開支。每次生成表單時,是否要調用散列函數來對列名進行編碼,並且在每次處理表單時解碼POST字段名稱?

您甚至不必混淆每個表單字段名稱以使混淆達到其效果。如果您的表單字段的某些甚至與數據庫列名稱不匹配,那麼攻擊者將不知道哪些匹配,哪些不匹配! :-)