SSRF 的全名是 Server-Side Request Forgery。這是一種極度危險的 Web 安全漏洞,它的核心概念是攻擊者濫用伺服器上的某個功能,誘使伺服器代替攻擊者,向其無法直接存取的內部網路或外部資源發起一個非預期的網路請求。
為了讓你更容易理解,我們延續之前「借刀殺人」的比喻:
簡單來說,SSRF 的本質就是:攻擊者找到一個方法,讓你的伺服器去訪問一個「只有伺服器自己才能訪問」的地方。
想像一個現代網站很常見的功能:「從 URL 上傳個人頭像」或「分析網頁內容」。
一個看似無害的功能:
網站上有個輸入框,讓使用者貼上一個圖片的 URL,伺服器會自動去下載這張圖片,並設為使用者的頭像。
伺服器的後端程式邏輯 (簡化版):
# 從使用者請求中取得 URL
image_url = request.GET.get('url')
# 伺服器直接向該 URL 發起請求,下載內容
image_content = requests.get(image_url)
# ...後續處理...
這段程式碼的問題在於,它完全信任了使用者提供的 image_url
,沒有做任何驗證就直接發起了網路請求。
攻擊者的惡意輸入:
攻擊者不會輸入一個正常的圖片網址,他會輸入:
http://192.168.1.1:8080/jenkins/login
(嘗試存取內網中可能存在的 Jenkins 自動化伺服器)file:///etc/passwd
(嘗試讀取伺服器作業系統的使用者列表檔案)http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLENAME
(這是 AWS 雲端主機的一個特殊內部地址,訪問它可以竊取到該主機的臨時存取金鑰!)伺服器被操控執行:
http://192.168.1.1:8080/jenkins/login
這個 URL 時,它會忠實地向這個內部地址發起請求。SSRF 的危害遠不止於探測,它可以導致:
file://
等協定,可以直接讀取伺服器上的設定檔、密碼檔等敏感資訊。防禦 SSRF 的核心思想是永不信任使用者提供的 URL,並對伺服器發出的請求進行嚴格的控制。
URL 白名單 (Whitelist) - 最有效的防禦:
在程式碼中硬編碼一份允許請求的域名/IP 白名單。只有當使用者提供的 URL 的主機部分完全匹配白名單中的項目時,才允許發起請求。這是最安全的方式。
限制請求協定 (Protocol Restriction):
根據業務需求,只允許 http
和 httpshttps
協定。嚴格禁止 file://
, gopher://
, dict://
, ftp://
等可能被用來讀取本地檔案或攻擊其他服務的危險協定。
解析 URL 並驗證主機:
在發起請求前,先解析使用者提供的 URL,取得其主機 (Hostname)。然後,將這個主機進行 DNS 解析,確保解析出的 IP 位址不是指向內部網路或本地迴環地址 (127.0.0.1
)。需要特別注意防範 DNS Rebinding 等繞過技巧。
統一出口與防火牆策略:
理想情況下,應用程式伺服器本身不應該能隨意訪問內網。應該設定一個統一的網路出口(例如 NAT Gateway),並在出口處配置嚴格的防火牆規則,只允許伺服器訪問經過審批的外部目標。
SSRF 是一個高權限的漏洞,它將伺服器本身變成了攻擊者的武器。在微服務和雲端架構日益普及的今天,服務與服務之間的調用非常頻繁,SSRF 的風險也隨之劇增,是所有開發者和架構師都必須高度重視的安全威脅。