首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Rails 應用安全防範全景圖:Session、CSRF、文件上傳、重定向與注入攻擊防禦

     編輯:Java 相關知識

Session 安全:防劫持、防固定、防洩露

Session 機制

HTTP 無狀態,Session 通過 session_id(32 字符 MD5)在 Cookie 中維持狀態。Rails 默認 CookieStore(客戶端存儲,Base64 編碼 + HMAC 簽名)或 ActiveRecord::SessionStore(服務端存儲)。

主要攻擊向量與對策

攻擊描述對策
側傾監聽公共 WiFi 竊取明文 Cookie強制 HTTPS:config.force_ssl = true (Rails 3.1+)
公共終端殘留用戶未登出直接離開顯眼的「登出」按鈕,敏感操作要求重新認證
XSS 竊取 Cookie惡意腳本讀取 document.cookieHttpOnly Cookie(Rails 默認開啟),嚴格輸出轉義
Session Fixation攻擊者預設 Session ID,誘導受害者登入登入後重置 Session:reset_session 或 session[:user_id] = user.id 觸發新 ID 生成
Session Replay (CookieStore)重放舊 Cookie 恢復舊狀態(如購物車金額)關鍵狀態存服務端(DB/Redis),Cookie 僅存標識符

Session 存儲選型建議

  • CookieStore:輕量、無狀態、適合小型應用。必須設置強密鑰(config.secret_key_base ≥ 30 字符隨機串)。
  • ActiveRecord/Cache/Redis Store:大對象、敏感數據、需服務端撤銷、分布式部署。定期清理過期記錄。

CSRF 跨站請求偽造:Rails 內建防護

攻擊原理

受害者登入目標站點 → 訪問惡意頁面 → 頁面自動提交表單/發起 AJAX 到目標站點 → 瀏覽器攜帶 Cookie 發送請求 → 服務端執行破壞操作(刪除、轉賬、改密)。

CSRF 攻擊流程

Rails 防護機制

  1. 正確使用 HTTP 動詞:GET 不修改數據;POST/PUT/DELETE/PATCH 修改數據。
  2. Authenticity Token:protect_from_forgery with: :exception(默認已開啟)。表單自動嵌入 csrf-token,AJAX 需在 Header 傳遞 X-CSRF-Token。
  3. 自定義異常處理:rescue_from ActionController::InvalidAuthenticityToken, with: :handle_invalid_token。

文件上傳與下載安全

上傳風險矩陣

風險示例防禦
路徑遍歷文件名 ../../../etc/passwd白名單校驗文件名(僅允許 [a-zA-Z0-9._-]),重命名存儲(UUID + 原擴展名)
腳本執行上傳 shell.php 訪問執行上傳目錄禁用執行權限(Nginx location /uploads { disable_functions ... }),存放於 Web 根目錄外
類型偽裝惡意 exe 改名為 image.jpg雙重驗證:content_type + 文件魔數(file 命令/mimemagic gem)
DoS 攻擊併發上傳大文件耗盡磁盤/內存異步處理(ActiveJob),限制單文件大小、併發數、用戶配額

安全上傳代碼模板

def create
  uploaded = params[:post][:picture]
  return head :bad_request unless uploaded
  
  # 1. 類型白名單
  allowed_types = %w[image/jpeg image/png image/gif application/pdf]
  return head :unsupported_media_type unless allowed_types.include?(uploaded.content_type)
  
  # 2. 魔數二次驗證
  return head :unsupported_media_type unless valid_magic_number?(uploaded)
  
  # 3. 安全存儲
  ext = File.extname(uploaded.original_filename).downcase
  safe_name = "#{SecureRandom.uuid}#{ext}"
  store_path = Rails.root.join('storage', 'uploads', safe_name)
  
  FileUtils.mkdir_p(File.dirname(store_path))
  File.open(store_path, 'wb') { |f| f.write(uploaded.read) }  # 關鍵:wb 二進制模式
  
  # 4. 記錄元數據
  @post.picture = safe_name
  @post.save!
end

下載安全

  • 數據庫存儲 id, logical_name, physical_path 映射,下載時通過 ID 查找物理路徑。
  • 使用 send_file 時絕不拼接用戶輸入:send_file(@document.physical_path, filename: @document.logical_name)。
  • 大文件啟用 X-Sendfile/X-Accel-Redirect 交給 Nginx/Apache 發送,釋放 Rails 進程。

重定向與注入攻擊防禦

非法重定向

參數 redirect_to params[:url] 可導向釣魚網站。白名單校驗:

ALLOWED_HOSTS = %w[example.com partner.com].freeze
def safe_redirect
  url = params[:redirect_url]
  if url.present? && ALLOWED_HOSTS.any? { |host| url.start_with?("https://#{host}") }
    redirect_to url
  else
    redirect_to root_path
  end
end

SQL 注入

Rails ActiveRecord 參數化查詢默認安全:

# 安全
User.where("email = ?", params[:email])
User.where(email: params[:email])

# 危險:字符串拼接
User.where("email = '#{params[:email]}'")  # ❌ 永不使用

命令注入

避免 system/`/%x 拼接用戶輸入。必須使用 Shellwords.escape 或 Open3.popen3 參數化調用。

總結:安全是系統工程

Rails 提供了強大的內建防護(CSRF Token、參數化查詢、HttpOnly Cookie、強制 SSL),但開發者必須:

  1. 理解攻擊原理,不盲目信任框架默認配置。
  2. 建立安全編碼規範(Code Review 必查項:文件上傳、重定向、原始 SQL、命令執行)。
  3. 持續更新依賴(bundle audit、brakeman 靜態掃描、訂閱 Rails Security 郵件列表)。
  4. 分層防禦:WAF、Nginx 限流、數據庫最小權限、審計日志、入侵檢測。

安全無絕對,唯有纏鬥到底。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved