Header Manipulation
Abstract
HTTP 響應頭文件中包含未驗證的數據會引發 cache-poisoning、 cross-site scripting、 cross-user defacement、 page hijacking、 cookie manipulation 或 open redirect。
Explanation
以下情況中會出現 Header Manipulation 漏洞:
- 數據通過一個不可信賴的數據源進入 Web 應用程序,最常見的是 HTTP 請求。
- 數據包含在一個 HTTP 響應頭文件里,未經驗證就發送給了 Web 用戶。 如同許多軟件安全漏洞一樣, Header Manipulation 只是通向終端的一個途徑,它本身並不是終端。 從本質上看,這些漏洞是顯而易見的: 一個攻擊者將惡意數據傳送到易受攻擊的應用程序,且該應用程序將數據包含在 HTTP 響應頭文件中。 其中最常見的一種 Header Manipulation 攻擊是 HTTP Response Splitting。 為了成功地實施HTTP Response Splitting 盜取,應用程序必須允許將那些包含 CR(回車,由 %0d 或 \r 指定)和 LF(換行, 由 %0a 或 \n 指定)的字符輸入到頭文件中。 攻擊者利用這些字符不僅可以控制應用程序要發送的響應剩余頭文件和正文,還可以創建完全受其控制的其他響應。 如今的許多現代應用程序服務器可以防止 HTTP頭文件感染惡意字符。 例如,如果嘗試使用被禁用的字符設置頭文件,最新版本的 Apache Tomcat 會拋出IllegalArgumentException。 如果您的應用程序服務器能夠防止設置帶有換行符的頭文件,則其具備對 HTTP Response Splitting 的防御能力。 然而,單純地過濾換行符可能無法保證應用程序不受 CookieManipulation 或 Open Redirects 的攻擊,因此必須在設置帶有用戶輸入的 HTTP 頭文件時采取措施。
例: 下列代碼片段會從 HTTP 請求中讀取網絡日志項的作者名字 author,並將其置於一個 HTTP 響應的 cookie 頭文件中。
String author = request.getParameter(AUTHOR_PARAM);
...
Cookie cookie = new Cookie("author", author);
cookie.setMaxAge(cookieExpiration);
response.addCookie(cookie);
假設在請求中提交了一個字符串,該字符串由標准的字母數字字符組成,如 "Jane Smith",那么包含該cookie 的 HTTP 響應可能表現為以下形式:
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
然而,因為 cookie 值來源於未經校驗的用戶輸入,所以僅當提交給 AUTHOR_PARAM 的值不包含任何 CR 和LF 字符時,響應才會保留這種形式。 如果攻擊者提交的是一個惡意字符串,比如
"Wiley Hacker\r\nHTTP/
1.1 200 OK\r\n..."
,那么 HTTP 響應就會被分割成以下形式的兩個響應:
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
顯然,第二個響應已完全由攻擊者控制,攻擊者可以用所需的頭文件和正文內容構建該響應。 攻擊者可以構建任意 HTTP 響應,從而發起多種形式的攻擊,包括: cross-user defacement、網絡和瀏覽器 cache poisoning、 cross-site scripting 和 page hijacking。 cross-user defacement: 攻擊者可以向一個易受攻擊的服務器發出一個請求,導致服務器創建兩個響應,其中第二個響應可能會被曲解為對其他請求的響應,而這一請求很可能是與服務器共享相同 TCP 連接的另一用戶發出的。 這種攻擊可以通過以下方式實現:攻擊者誘騙用戶,讓他們自己提交惡意請求;或在遠程情況下,攻擊者與用戶共享同一個連接到服務器(如共享代理服務器)的 TCP 連接。 最理想的情況是,攻擊者只能通過這種做法讓用戶相信自己的應用程序已經遭受了黑客攻擊,進而對應用程序的安全性失去信心。 最糟糕的情況是,攻擊者可能提供經特殊技術處理的內容,這些內容旨在模仿應用程序的執行方式,但會重定向用戶的私人信息(如帳號和密碼),將這些信息發送給攻擊者。 cache-poisoning: 如果多用戶 Web 緩存或者單用戶瀏覽器緩存將惡意構建的響應緩存起來,該響應的破壞力會更大。 如果響應緩存在共享的 Web 緩存(如在代理服務器中常見的緩存)中,那么使用該緩存的所有用戶都會不斷收到惡意內容,直到清除該緩存項為止。 同樣,如果響應緩存在單個用戶的瀏覽器中, 那么在清除該緩存項以前,該用戶會不斷收到惡意內容。然而,影響僅局限於本地瀏覽器的用戶。
Cross-Site Scripting:
一旦攻擊者控制了應用程序傳送的響應,就可以選擇多種惡意內容來傳播給用戶。Cross-Site Scripting 是最常見的攻擊形式,這種攻擊在響應中包含了惡意的 JavaScript 或其他代碼,並在用
戶的瀏覽器中執行。 基於 XSS 的攻擊手段花樣百出,幾乎是無窮無盡的,但通常它們都會包含傳輸給攻擊者的私人數據(如 Cookie 或者其他會話信息)。在攻擊者的控制下,指引受害者進入惡意的網絡內容;或者利用易受攻擊的站點,對用戶的機器進行其他惡意操作。 對於易受攻擊的應用程序用戶,最常見且最危險的攻擊就是使用 JavaScript 將會話和 authentication 信息返回給攻擊者,而后攻擊者就可以完全控制受害者的帳號了。
Page Hijacking:
除了利用一個易受攻擊的應用程序向用戶傳輸惡意內容,還可以利用相同的根漏洞, 將服務器生成的供用戶使用的敏感內容重定向,轉而供攻擊者使用。 攻擊者通過提交一個會導致兩個響
應的請求,即服務器做出的預期響應和攻擊者創建的響應,致使某個中間節點(如共享的代理服務器)誤導服務器所生成的響應,將本來應傳送給用戶的響應錯誤地傳給攻擊者。 因為攻擊者創建的請求產生了兩個響應, 第一個被解析為針對攻擊者請求做出的響應,第二個則被忽略。 當用戶通過同一 TCP 連接發出合法請求時, 攻擊者的請求已經在此處等候,並被解析為針對受害者這一請求的響應。 這時,攻擊者將第二個請求發送給服務器,代理服務器利用針對受害者(用戶)的、由該服務器產生的這一請求對服務器做出響應,因此, 針對受害者的這一響應中會包含所有頭文件或正文中的敏感信息。
Cookie Manipulation:
當與類似Cross-Site Request Forgery 的攻擊相結合時,攻擊者就可以篡改、添加、甚至覆蓋合法用戶的 cookie。
Open Redirect:
如果允許未驗證的輸入來控制重定向機制所使用的 URL,可能會有利於攻擊者發動釣魚攻擊。
Recommendation
針對 Header Manipulation 的解決方法是,確保在適當位置進行輸入驗證並檢驗其屬性是否正確。 由於Header Manipulation 漏洞出現在應用程序的輸出中包含惡意數據時,因此,合乎邏輯的做法是在應用程序輸出數據前一刻對其進行驗證。 然而,由於 Web 應用程序常常會包含復雜而難以理解的代碼,用以生成動態響應,因此,這一方法容易產生遺漏錯誤(遺漏驗證)。 降低這一風險的有效途徑是對 Header Manipulation 也執行輸入驗證。 由於 Web 應用程序必須驗證輸入信息以避免出現其他漏洞(如 SQLInjection),因此,一種相對簡單的解決方法是擴充應用程序現有的輸入驗證機制,增加針對 HeaderManipulation 的檢查。 盡管具有一定的價值,但 Header Manipulation 輸入驗證並不能取代嚴格的輸出驗證。 應用程序可能通過共享的數據存儲或其他可信賴的數據源接受輸入,而該數據存儲所接受的輸入源可能並未執行適當的輸入驗證。 因此,應用程序不能間接地依賴於該數據或其他任意數據的安全性。 這就意味着, 避免 Header Manipulation 漏洞的最佳方法是驗證所有應用程序輸入數據或向用戶輸出的數據。 針對Header Manipulation 漏洞進行驗證最安全的方式是創建一份安全字符白名單,其中的字符允許出現在 HTTP響應頭文件中,並且只接受完全由這些受認可的字符組成的輸入。 例如,有效的用戶名可能僅包含字母數字字符,帳號可能僅包含 0-9 的數字。 更靈活的解決方法稱為黑名單方法,但其安全性較差,這種方法在進行輸入之前就有選擇地拒絕或避免了潛在的危險字符。 為了創建這樣的列表,首先需要了解在 HTTP 響應頭文件中具有特殊含義的一組字符。 盡管 CR 和 LF 字符是 HTTP Response Splitting 攻擊的核心,但其他字符,如 ":" (冒號)和 "="(等號),在響應頭文件中同樣具有特殊的含義。 一旦在應用程序中確定了針對Header Manipulation 攻擊執行驗證的正確點,以及驗證過程中要考慮的特殊字符,下一個難題就是確定在驗證過程中該如何處理各種特殊字符。 應用程序應拒絕任何要添加到 HTTP 響應頭文件中的包含特殊字符的輸入, 這些特殊字符(特別是 CR 和 LF)是無效字符。 許多應用程序服務器都試圖避免應用程序出現 HTTP
Response Splitting 漏洞,其做法是為負責設置 HTTP 頭文件和 cookie 的函數提供各種執行方式,以檢驗是否存在進行 HTTP Response Splitting 攻擊必需的字符。 不要依賴運行應用程序的服務器,以此確保該應用程序的安全。 開發了某個應用程序后,並不能保證在其生命周期中它會在哪些應用程序服務器中運行。 由於標准和已知盜取方式的演變,我們不能保證應用程序服務器也會保持同步。