四 重定向和文件
另一類安全問題是圍饒在web應用裡重定向和文件的使用。
4.1 重定向
web應用裡的重定向是一個被低估的craker工具:它不僅可以讓用戶掉入一個陷進網站,而且還可以創造一個完備的攻擊。
當用戶被允許由一個URL重定向的時候,它由可能就是個漏洞。最明顯的攻擊是將用戶重定向到一個和原始頁面一模一樣的假頁面。這個所 謂的‘釣魚攻擊’通過給用戶發送一封包含正常的不讓人起疑的鏈接的email, 通過XSS方式往web應用裡注射這個惡意鏈接或者把鏈接放到一 個虛假的網站(域名看起來差不多,頁面也相同的站點)。它是毫不讓人懷疑的,因為這個鏈接的起始URL是這個正常的web應用,指向惡意站 點的URL都被隱藏在重定向參數裡:http://www.example.com/site/redirect?to= www.attacker.com. 這裡由個例子:
def legacy
redirect_to(params.update(:action=>'main'))
end
如果用戶訪問legacy這個action,將會被重定向到mail action。這樣做的意圖是為了維護legacy的參數,並把這些參數傳到main action。 但是,如果它包含了一個host key,就會被攻擊者利用。
http://www.example.com/site/legacy?param1=xy¶m2=23&host=www.attacker.com
如果它在url的尾部, 將很難被注意到,用戶就被神不知鬼不覺的重定向到了攻擊者的頁面。一個簡單的對策是,在legacy action裡只包 含預期的參數(白名單的辦法,不是取消所有意向不到的參數)。如果你重定向到一個網址,你需要用白名單或是正則表達式檢查它。
4.1.1 Self-contained XSS(自載的xss攻擊)
另一個重定向和self-contained XSS 攻擊是通過firefox和opera裡使用的一種數據協議。該協議直接在浏覽器裡顯示其內容,可以使任何 內容,從html,javascript到圖片。(這不是一個漏洞,而是一個功能)
data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K
這個例子是一個Base64編碼的顯示簡單消息框的javascript。在一個重定向的URL裡,一個攻擊者能用它裡面的惡意代碼重定向這個url。
更詳細的攻擊原理可以參看這裡:http://www.gnucitizen.org/blog/self-contained-xss-attacks/
對策:do not allow the user to supply (parts of) the URL to be redirected to.(說實話,這裡我沒看明白)
4.2 文件上傳
- 確保文件上次不覆蓋重要的文件,和同步的媒體文件進程。
很多web應用允許用戶上傳文件,用戶可以選擇的文件名字,應該隨時被過濾,因為攻擊者可以用惡意的文件名覆蓋服務器上任意文件。如 果你在/var/www/uploads存儲上傳文件,用戶輸入一個文件名:../../../etc/passwd, 它可能覆蓋一個重要文件。
當過濾用戶輸入的文件名時,不要試圖去刪除惡意的部分。想一想,如果去掉所有的../ , 攻擊者輸入.. .. //, 那麼結果就成了../。最 好是用白名單的方式,用一套可接受的字符去檢查文件名的有效性。一旦它不是一個有效的文件名,則拒絕它(或替換它),但是不刪除它們 。這有一份來自attachment_fu插件的文件名清單:
def sanitize_filename(filename)
returning filename.strip do |name|
# NOTE: File.basename doesn't work right with Windows paths on Unix
# get only the filename, not the whole path
name.gsub! /^.*(\\|\/)/, ''
# Finally, replace all non alphanumeric, underscore
# or periods with underscore
name.gsub! /[^\w\.\-]/, '_'
end
end
一個重大的缺陷是,同步處理文件上傳(比如attachment_fu插件處理多個圖片上傳),使其易受dos攻擊。攻擊者可以從很多電腦同時啟動 圖像上傳,從而增加服務器負載,最終讓服務器崩潰。
要解決這一點,最好是異步處理媒體文件。Save the media file and schedule a processing request in the database. A second process will handle the processing of the file in the background.
4.3 Executable code in file uploads
- 上傳文件裡的代碼在特定的環境下可能被執行,如果Rails / Public 目錄是Apache的主目錄,請不要把文件上傳到此。
如果一個攻擊者上傳個file.cgi, 有人下載這個文件,代碼就會被執行。
4.4 File downloads
- 確保用戶無法下載任意文件。
正如你必須過濾上傳的文件名一樣,對下載文件也應該這樣做。下面這個send_file()方法發送文件到客戶端,如果你用了一個文件名沒有 過濾, 用戶輸入什麼都可以被下載。
send_file('/var/www/uploads/' + params[:filename])
簡單的通過“../../../etc/passwd”這樣一個文件名去下載服務器的登陸信息。簡單的解決方式是,檢查請求的文件是在允許的目錄下:
basename = File.expand_path(File.join(File.dirname(__FILE__), '../../files'))
filename = File.expand_path(File.join(basename, @file.public_filename))
raise if basename =!
File.expand_path(File.join(File.dirname(filename), '../../../'))
send_file filename, :disposition => 'inline'
另外一個方式是在數據庫裡存儲文件名。這種方式可以避免上傳文件的代碼被執行。attachment_fu用的就是類似的方式。