我希望允許用戶通過跟蹤URL來查看我的數據庫中的記錄。在數據庫表中有兩個唯一ID的錯誤想法?
我猜測它不是一個好主意,有這種類型的網址,其中記錄的標識符是記錄自動增量ID!
http://www.example.com/$db_record_id
以上是不必要的信息。這是真的嗎?不會爲每一行創建我自己的ID會造成同樣的問題?
有沒有更好的方法來解決我的問題。
環境:LAMP(PHP)
感謝所有
我希望允許用戶通過跟蹤URL來查看我的數據庫中的記錄。在數據庫表中有兩個唯一ID的錯誤想法?
我猜測它不是一個好主意,有這種類型的網址,其中記錄的標識符是記錄自動增量ID!
http://www.example.com/$db_record_id
以上是不必要的信息。這是真的嗎?不會爲每一行創建我自己的ID會造成同樣的問題?
有沒有更好的方法來解決我的問題。
環境:LAMP(PHP)
感謝所有
如果我是你,我想你的桌子上 使用整數主鍵(自動IDENT),並添加一個GUID上有一個唯一約束&指數,默認爲UUID()
然後鑽機你的頁面將在URL上取一個GUID並用它來搜索你的表格。
你給了一個非常有用的答案信息太少。
也就是說,我同意公開這樣的ID是有問題的。 commmon解決方案是在每次爲數據庫查詢一組記錄時生成臨時ID,並在內部存儲tempID-> real ID。然後將這些臨時ID放入URL中,並在服務器上進行翻譯。
你給出來的信息兩個部分組成:記錄
設定難道這些東西問題爲您的應用程序,然後使用其他東西
您可以使用GUID的Db鍵,但這可能會影響大數據集中的潛在性能。
將記錄的id放入URL通常不是問題。例如,查看這個瀏覽器窗口的URL,你會看到這個問題的ID。
如果您出於某種原因不希望ID清晰可見,則可以對值進行加擾或加密。如果您需要保護某些記錄以免被查看,那麼這當然不是一種安全的方法,那麼您必須將其與某種身份驗證相結合,例如登錄用戶的會話ID。
編輯:
爲了正確的安全,人們必須關注真正的問題。如果某些頁面的訪問權限受到限制,問題不在於任何人都可以找出頁面的URL,問題是任何人都可以查看該頁面。一個URL總是可以以某種方式獲得(例如,包嗅探),所以安全性必須以其他方式實現。
也許你應該公開另一個唯一的標識符,比如標題而不是主鍵?暴露你的PK並不會造成安全風險,但是如果你可以暴露其他屬性,你可能會在搜索結果上更高。
該方法的一個可能的問題是,對於某人通過在URL中順序增加ID來檢索所有頁面/記錄是非常容易的。這可能不是你想要的,但是不管怎樣,你都不應該依靠使用隱蔽的URL來保證安全。
一些其他的選擇將是:
這不是一個好主意,因爲它已經說過了(你實際上暴露了表中的每一行),我不認爲這是必要的。我想用戶會在某個場景(從列表或其他任何東西中選擇一個元素)後到達那個頁面,所以你將有一個頁面提交和一個控制器(如果你正在嘗試使用MVC架構)它將處理任何需要的處理,並且它將發送到可能僅僅是一個查看頁面www.yoursite.com/displayElement.htm
通過這種方式,ID只是作爲會話變量傳遞並且不顯示在任何地方。
但是萬一我弄錯了,你顯示的是某種目錄,所以你希望用戶能夠書寫頁面,比你只需要添加一些混淆機制,將創建一個複雜的字符串基於ID,在將ID發送到URL並在代碼中對其進行解碼以獲得實際ID之前對ID進行編碼。
用戶請求中的主鍵本身並不脆弱。只需將其轉換爲整數值即可,這就是全部
$id = (int)$id;
。
另一個問題是關於限制某些記錄訪問。您可以通過簡單編輯查詢來解決這個問題,並添加一些訪問規則。例如,如果你有型管理/編輯器/閱讀/客的用戶,你可以保存在SET領域的訪問權限,並添加到您的查詢條件
SELECT ...
FROM mytable
WHERE
id = (int)$id
AND
(FIND_IN_SET('admin', access) OR FIND_IN_SET('editor', access))
...
if (!$fetch = mysql_fetch_acssoc($res))
throw new Exception('Record not found or you have no permission to access it');
所以,不用擔心華南簡介主鍵 - 他們很如果您不忘記將它們轉換爲整數以避免SQL注入,則可以安全使用。
如果用戶無論如何都可以看這個頁面,我看到使用這個id沒有問題。如果他們想要更改網址並轉到隨機頁面,我不會有任何問題。
如果網頁不被任何人觀看,我實際上仍然沒有問題。因爲如果是這樣的話,你應該進行一些授權檢查,以防止他們看到他們不被允許看到的頁面。
您所描述的是稱爲Direct Object Reference的漏洞。這些並不是固有的壞處,但是Insecure Direct Object References是並且是OWASP十強中的第四名。
您可以通過檢查屬於當前用戶的對象來確保直接對象引用,如果它沒有顯示它。
此外,即使訪問被拒絕的消息也可能泄露信息。例如,如果你的參數是一個訂單號,攻擊者可以發現你的公司實際上有多少訂單,即使你不通過簡單地增加數量直到他們得到404來顯示它們。
就我個人而言, GUID作爲間接對象引用的一種形式,但顯然不是數據庫中的主鍵。
的威脅水平取決於範圍和對象:
總的來說,我贊成可預測的URL。這就是說,重要的是要考慮如何使用它們以及誰可以看到它們。
如果你想確保人們不只是猜測URL的,那麼這是一個簡單的方法。這絕不是安全(即不要使用這種方法進行訪問檢查),但它會確保你不能只是輸入一個隨機的URL,並得到sendt到該頁面。
使用url中的另一條信息補充ID。我建議使用id的鹽味散列。
當生成一個網址:
$id = 5;
$hash = md5($id . "MY_SALT_VALUE");
$url = "/$id/$hash";
和顯示記錄時:
$params = explode(',', $_SERVER['REQUEST_URL']);
$id = $params[0];
$hash = $params[1];
if($hash != md5($id ."MY_SALT_VALUE")) {
die('Uh oh! You guessed the URL, didn\'t you! Bad user!');
}
$data = $MyModel->load($id);
if(!$data) {
die('No such record');
}
DisplayModel($data);
當然,這是一個樣機(說在錯誤信息太多,只是die()
荷蘭國際集團的,而不是正確的404頁面,等等)。
該URL將由我的PHP腳本生成。我正在考慮使用我自己的唯一ID,這些ID是增量式的並涉及字母的使用。我的Web應用程序將查看URL並使用URL末尾的ID來匹配數據庫記錄。 – Abs 2009-06-04 08:18:47
那麼,你永遠不應該信任客戶端,所以你應該在查詢中使用它之前驗證URL中的ID。如果你這樣做,你的方法應該沒問題。 – sleske 2009-06-04 08:22:34
我會避免使用任何「可猜測」的東西。 UUID將完全無法猜測,並且會阻止厚顏無恥的用戶隨機輸入不同的值。任何你自己嘗試和實現的東西(除非是完全僞隨機的)你自己的密鑰,也許是用戶可以猜測的 – 2009-06-04 08:38:37