用戶可控重定向 URL 是被低估的攻擊向量:
https://app.com/redirect?to=evil.comdata: 協議 data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K(Base64 編碼 ``)def legacy
redirect_to(params.update(:action => 'main'))
end
# 攻擊: /legacy?param1=xy&host=evil.com
# params[:host] 被 redirect_to 採納 → 重定向至惡意站點
redirect_to(:action => 'main', :id => params[:id])攻擊者上傳 ../../../etc/passwd 覆蓋系統檔案。勿用黑名單移除 ../(雙重編碼繞過:..// → ../)。
# attachment_fu 白名單做法
def sanitize_filename(filename)
filename.strip!
name = filename.gsub(/^.*(\\|\/)/, '') # 只取檔名
name.gsub!(/[^\w\.\-]/, '_') # 非英數/底線/點/連字號 → 底線
name
end
大量並發上傳佔用資源 → 服務癱瘓。對策:非同步處理 —— 儲存檔案 → 資料庫排程 → 背景 Worker 處理(縮圖、轉碼等)。
若 public/ 為 Apache DocumentRoot,上傳 shell.cgi 經由 URL 直接執行。對策:
public/ 外部SetHandler default-handler 強制靜態檔案模式# 危險
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 "Invalid path" unless filename.start_with?(basename)
send_file filename, :disposition => 'inline'
替代方案:資料庫儲存檔名/路徑,完全避免路徑遍歷。