前端安全機制與解決方案


一、概述

  “安全”是個很大的話題,各種安全問題的類型也是種類繁多。如果我們把安全問題按照所發生的區域來進行分類的話,那么所有發生在后端服務器、應用、服務當中的安全問題就是“后端安全問題”,所有發生在瀏覽器、單頁面應用、Web頁面當中的安全問題則算是“前端安全問題”。比如說,SQL注入漏洞發生在后端應用中,是后端安全問題,跨站腳本攻擊(XSS)則是前端安全問題,因為它發生在用戶的瀏覽器里。

二、常見前端安全問題及防護

1、跨站腳本攻擊(Cross-Site Scripting)

  XSS是跨站腳本攻擊(Cross-Site Scripting)的簡稱。XSS這類安全問題發生的本質原因在於:瀏覽器錯誤的將攻擊者提供的用戶輸入數據當做JavaScript腳本給執行了。
  XSS有幾種不同的分類辦法,例如按照惡意輸入的腳本是否在應用中存儲,XSS被划分為“存儲型XSS”和“反射型XSS”,如果按照是否和服務器有交互,又可以划分為“Server Side XSS”和“DOM based XSS”。
  無論怎么分類,XSS漏洞始終是威脅用戶的一個安全隱患。攻擊者可以利用XSS漏洞來竊取包括用戶身份信息在內的各種敏感信息、修改Web頁面以欺騙用戶,甚至控制受害者瀏覽器,或者和其他漏洞結合起來形成蠕蟲攻擊,等等。總之,關於XSS漏洞的利用,只有想不到沒有做不到。

  如何防御?

  對數據進行嚴格的輸出編碼,使得攻擊者提供的數據不再被瀏覽器認為是腳本而被誤執行。例如<script>在進行HTML編碼后變成了&lt;script&gt;,這段數據就不會被當做腳本執行了。
需要根據輸出數據所在的上下文來進行相應的編碼。數據放置於HTML元素中,需進行HTML編碼,放置於URL中,需要進行URL編碼。此外,還有JavaScript編碼、CSS編碼、HTML屬性編碼、JSON編碼等等。(一些主流前端開發框架基本上都默認提供了前端輸出編碼,這大大減輕了前端開發小伙伴們的工作負擔)
  其他的防御措施,例如設置CSP HTTP Header、輸入驗證、開啟瀏覽器XSS防御等等都是可選項,原因在於這些措施都存在被繞過的可能,並不能完全保證能防御XSS攻擊。不過它們和輸出編碼卻可以共同協作實施縱深防御策略。


2、使用iframe的風險

  有時前端頁面需要用到第三方提供的頁面組件,通常會以iframe的方式引入。典型的例子是使用iframe在頁面上添加第三方提供的廣告、天氣預報、社交分享插件等等。  
  iframe在給我們的頁面帶來更多豐富的內容和能力的同時,也帶來了不少的安全隱患。因為iframe中的內容是由第三方來提供的,默認情況下他們不受我們的控制,他們可以在iframe中運行JavaScirpt腳本、Flash插件、彈出對話框等等,這可能會破壞前端用戶體驗。
  如果說iframe只是有可能會給用戶體驗帶來影響,看似風險不大,那么如果iframe中的域名因為過期而被惡意攻擊者搶注,或者第三方被黑客攻破,iframe中的內容被替換掉了,從而利用用戶瀏覽器中的安全漏洞下載安裝木馬、惡意勒索軟件等等,這問題可就大了。

  如何防御?

  在HTML5中,iframe有個sandbox安全屬性,通過它可以對iframe的行為進行各種限制,充分實現“最小權限“原則。例如: <iframe sandbox src="..."> ... </iframe>
sandbox提供了豐富的配置參數,可以進行較為細粒度的控制。
  allow-forms:允許iframe中提交form表單
  allow-popups:允許iframe中彈出新的窗口或者標簽頁(例如,window.open(),showModalDialog(),target=”_blank”等等)
  allow-scripts:允許iframe中執行JavaScript
  allow-same-origin:允許iframe中的網頁開啟同源策略
  更多詳細的資料,可以參考iframe中關於sandbox的介紹。


3、點擊劫持

  這是一種欺騙性比較強,同時也需要用戶高度參與才能完成的一種攻擊。通常的攻擊步驟是這樣的:
  1、攻擊者構造一個誘導用戶點擊的內容,如Web頁面小游戲
  2、將被攻擊的頁面放入到iframe當中
  3、利用z-index等CSS樣式將這個iframe疊加到小游戲的垂直方向的正上方
  4、把iframe設置為100%透明度
  5、受害者訪問這個頁面,肉眼看到的是一個小游戲,如果受到誘導進行了點擊的話,實際上點擊到的卻是iframe中的頁面
  點擊劫持的危害在於,攻擊利用了受害者的用戶身份,在其不知情的情況下進行一些操作。

如何防御?

  有多種防御措施都可以防止頁面遭到點擊劫持攻擊,例如Frame Breaking方案。一個推薦的防御方案是,使用X-Frame-Options:DENY 這個HTTP Header來明確的告知瀏覽器,不要把當前HTTP響應中的內容在HTML Frame中顯示出來。

  關於點擊劫持更多的細節,可以查閱OWASP Clickjacking Defense Cheat Sheet。鏈接地址: https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet


4、錯誤的內容推斷

  攻擊場景:某網站允許用戶在評論里上傳圖片,攻擊者將含有惡意JavaScript的腳本文件擴展名改成圖片格式進行上傳(這涉及到了惡意文件上傳這個常見安全問題,但是由於和前端相關度不高因此暫不詳細介紹)。接下來,受害者在訪問這段評論的時候,瀏覽器會去請求這個偽裝成圖片的JavaScript腳本,而此時如果瀏覽器錯誤的推斷了這個響應的內容類型(MIME types),那么就會把這個圖片文件當做JavaScript腳本執行,於是攻擊也就成功了。
  問題的關鍵:后端服務器在返回的響應中設置的Content-Type Header僅僅只是給瀏覽器提供當前響應內容類型的建議,而瀏覽器有可能會自作主張的根據響應中的實際內容去推斷內容的類型。
  上例中,后端通過Content-Type Header建議瀏覽器按圖片來渲染HTTP響應,但瀏覽器發現響應的其實是JavaScript,於是就擅自做主把這段響應當做JS腳本來解釋執行,安全問題也就產生了。

如何防御?
  瀏覽器根據響應內容來推斷其類型,本來這是個很“智能”的功能,是瀏覽器強大的容錯能力的體現,但是卻會帶來安全風險。要避免出現這樣的安全問題,辦法就是通過設置X-Content-Type-Options這個HTTP Header明確禁止瀏覽器去推斷響應類型。
  同樣是上面的攻擊場景,后端服務器返回的Content-Type建議瀏覽器按照圖片進行內容渲染,瀏覽器發現有X-Content-Type-Options HTTP Header的存在,並且其參數值是nosniff,因此不會再去推斷內容類型,而是強制按照圖片進行渲染,從而最終防止了安全問題的發生。
  更多關於X-Content-Type-Options的細節請參考: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options


5、不安全的第三方依賴包

  現如今進行應用開發,無論是后端服務器應用還是前端應用開發,絕大多數時候我們都是在借助開發框架和各種類庫進行快速開發。
  這樣做的好處顯而易見,但是與此同時安全風險也在不斷累積——應用使用了如此多的第三方代碼,不論應用自己的代碼的安全性有多高,一旦這些來自第三方的代碼有安全漏洞,那么對應用整體的安全性依然會造成嚴峻的挑戰。

如何防御?

  盡量減少第三方依賴,選用相對成熟的依賴包。
  使用自動化工具檢查這些第三方代碼有沒有安全問題,比如NSP(Node Security Platform),Snyk等等。


6、HTTPS中間人攻擊

  即使是服務器端開啟了HTTPS,也還是存在安全隱患,黑客可以利用SSL Stripping這種攻擊手段,強制讓HTTPS降級回HTTP,從而繼續進行中間人攻擊。
  問題的本質在於瀏覽器發出去第一次請求就被攻擊者攔截了下來並做了修改,根本不給瀏覽器和服務器進行HTTPS通信的機會。大致過程如下,用戶在瀏覽器里輸入URL的時候往往不是從https://開始的,而是直接從域名開始輸入,隨后瀏覽器向服務器發起HTTP通信,然而由於攻擊者的存在,它把服務器端返回的跳轉到HTTPS頁面的響應攔截了,並且代替客戶端和服務器端進行后續的通信。由於這一切都是暗中進行的,所以使用前端應用的用戶對此毫無察覺。

如何防御?

  解決這個安全問題的辦法是使用HSTS(HTTP Strict Transport Security),它通過下面這個HTTP Header以及一個預加載的清單,來告知瀏覽器在和網站進行通信的時候強制性的使用HTTPS,而不是通過明文的HTTP進行通信:

  Strict-Transport-Security: max-age=; includeSubDomains; preload

  這里的“強制性”表現為瀏覽器無論在何種情況下都直接向服務器端發起HTTPS請求,而不再像以往那樣從HTTP跳轉到HTTPS。另外,當遇到證書或者鏈接不安全的時候,則首先警告用戶,並且不再讓用戶選擇是否繼續進行不安全的通信。

 

7 、本地存儲數據泄露

  隨着前后端分離,尤其是后端服務無狀態化架構風格的興起,隨着SPA應用大量出現,存儲在前端數據量也在逐漸增多。

  前端應用是完全暴露在用戶以及攻擊者面前的,在前端存儲任何敏感、機密的數據,都會面臨泄露的風險,就算是在前端通過JS腳本對數據進行加密基本也無濟於事。

  盡管有瀏覽器的同源策略限制,但是如果前端應用有XSS漏洞,那么本地存儲的所有數據就都可能被攻擊者的JS腳本讀取到。如果用戶在公用電腦上使用了這個前端應用,那么當用戶離開后,這些數據是否也被徹底清除了呢?前端對數據加密后再存儲看上去是個防御辦法,但其實僅僅提高了一點攻擊門檻而已,因為加密所用到的密鑰同樣存儲在前端,有耐心的攻擊者依然可以攻破加密這道關卡。

  所以,在前端存儲敏感、機密信息始終都是一件危險的事情,推薦的做法是盡可能不在前端存這些數據。

如何防御?

 

8 、CDN劫持/污染

  以出於性能考慮,前端應用通常會把一些靜態資源存放到CDN上,再提高前端應用的訪問速度的同時也隱含了一個新的安全風險。

如果攻擊者劫持了CDN,或者對CDN中的資源進行了污染,那么我們的前端應用拿到的就是有問題的JS腳本或者Stylesheet文件。這種攻擊方式造成的效果和XSS跨站腳本攻擊相似。

如何防御?

  防御這種攻擊的辦法是使用瀏覽器提供的SRI(Subresource Integrity)功能。

  每個資源文件都有一個SRI值。由兩部分組成,減號(-)左側是生成SRI值用到的哈希算法名,右側是經過Base64編碼后的該資源文件的Hash值。 <script src="“https://example.js”" integrity="“sha384-eivAQsRgJIi2KsTdSnfoEGIRTo25NCAqjNJNZalV63WKX3Y51adIzLT4So1pk5tX”"/>

  瀏覽器在處理這個script元素的時候,就會檢查對應的JS腳本文件的完整性,看其是否和script元素中integrity屬性指定的SRI值一致,如果不匹配,瀏覽器則會中止對這個JS腳本的處理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM