無cookie會話

 我們承認這一點 — 我們對會話狀態這一概念是如此習以爲常,以至於我們忘記了會話狀態是在 1997 年用 Active Server Pages (ASP) 引入的一個手段。會話狀態使開發人員能夠在用戶與應用程序交互這段時間內持久保存有關該用戶的一塊信息。特定於用戶的信息通常會保留 20 分鐘長的時段,而每當用戶返回該站點時,該時段都將重新開始計時。

當用戶首次連接到站點時,將以內存塊的形式創建一個全新的會話狀態以存放數據,同時,還會創建一個 ID 以便將其與當前用戶唯一地聯繫起來。當下一次發出請求時,該用戶將被要求提交該會話 ID,以便檢索並正確地還原會話狀態。會話 ID 是 ASP 和 ASP.NET 完全自主生成的字母數字字符串。用戶如何管理它並確保用每個後續請求來包裝它呢?

HTTP 協議的性質是無狀態的,並且沒有任何人試圖更改這一事實。差不多二十年以前,當 Netscape Corporation 開發它的第一個瀏覽器時,它“發明”了一種通過 HTTP 工作的持久性機制。它將其稱爲 HTTP Cookie。有趣的是,計算機科學行話中的術語“Cookie”僅僅表示一塊由應用程序持有的不透明數據,它會影響用戶但永遠不會由用戶直接管理。

因此,Cookie 存儲會話的 ID,而瀏覽器則在 Web 服務器和本地用戶的計算機之間來回移動它們的內容。當啓用了 Cookie 的瀏覽器收到響應數據包時,它將尋找附加的 Cookie,並將它們的內容存儲到本地 Windows 目錄中特定文件夾的某個文本文件中。Cookie 還包含有關該源站點的信息。接下來,當瀏覽器向該站點發送請求時,它會在 Cookie 文件夾中查找源自該域的 Cookie。如果找到,則該 Cookie 自動附加到傳出的數據包中。該 Cookie 將命中服務器應用程序,並在此被檢測、提取和處理。

最終,Cookie 使 Web 站點更加易於導航,因爲它們在用戶體驗之上提供了必然跨越多個請求的連續性錯覺。

Cookies 是不是一個問題?

多年以來,Cookie 只被視爲一種技術功能,並且在很大程度上被忽略了。幾年以前,針對 Web 安全的世界範圍的浪潮將人們的注意力集中於 Cookie 身上。Cookie 被斷定包含危險的程序,它們甚至能夠超出計算機的物理邊界來竊取有價值的信息。

不言而喻,Cookie 不是程序,因而無法自行收集任何信息 — 更不用說有關用戶的任何個人信息。更加清楚的是,Cookie 是 Web 站點可以放置在用戶的計算機中以便以後檢索和重用的一段文本。所存儲的信息是由無害的名稱-值對組成的。

要點在於,Cookie 不是標準 HTTP 規範的一部分,因此它們意味着瀏覽器和 Web 站點之間的一種協作。並非所有瀏覽器都支持 Cookie,而且更爲重要的是,並非所有用戶都在他們自己的瀏覽器副本中啓用 Cookie 支持。

在歷史上,有一些 Web 站點功能是如此緊密地與 Cookie 相聯繫,以至於很難區分究竟是哪個功能最先出現。一方面,用 Cookie 對會話狀態管理和用戶身份驗證進行編碼要容易得多。另一方面,如果您觀察一下站點與用於訪問頁的瀏覽器有關的統計信息,那麼您可能會驚訝地發現,相當一部分用戶在連接時禁用了 Cookie。這一點會對開發人員有所啓示。

總而言之,Cookie 本身並不是問題,但它們的使用無疑給予一些服務器代碼在客戶端計算機中存儲一段數據的能力。這預示着一些潛在的安全風險和一種不夠理想的總體狀況。(在某些情況以及某些國家/地區中,應用程序要求 Cookie 工作甚至是非法的。)

 

進入無 Cookie 會話

在 ASP.NET 中,無需使用 Cookie,就可以有選擇地建立必要的會話-用戶聯繫。非常有趣的是,除了以下配置設置以外,您無需在 ASP.NET 應用程序中更改任何內容即可啓用無 Cookie 會話。

<sessionState cookieless="true" /> 

ASP.NET 會話狀態的默認設置是在 machine.config 文件中定義的,並且可以在應用程序根文件夾中的 web.config 文件中重寫。通過確保上述行出現在根 web.config 文件中,您可以啓用無 Cookie 會話。就是這樣 — 簡單而有效!

<sessionState>節點還可以用於配置會話狀態管理的其他方面,包括存儲介質和連接字符串。但是,就 Cookie 而言,只需您將 cookieless 屬性設置爲 true(默認設置爲 false)。

請注意,會話設置是應用程序範圍的設置。換句話說,您站點中的頁要麼都將使用要麼都將不使用 Cookie 來存儲會話 ID。

當不使用 Cookie 時,ASP.NET 在哪裏存儲會話 ID 呢?在這種情況下,會話 ID 插入到 URL 內的特定位置中。下圖顯示一個使用無 Cookie 會話的真實站點的快照。


1. 使用無 Cookie 會話的 MapPoint

假設您請求了一個類似於 http://yourserver/folder/default.aspx 的頁。正如您可以從 MapPoint 快照中看到的那樣,資源名稱前面的相鄰斜槓進行了擴展,以便包含在內部填充了會話 ID 的括號,如下所示。

http://yourserver/folder/(session ID here)/default.aspx

會話 ID 嵌入到 URL 中,並且無需在其他任何地方持久保存它。唔,並不完全是這樣。請考慮以下方案。

您訪問了一個頁,並且被分配了一個會話 ID。接下來,您清除了同一瀏覽器示例的地址欄,轉到另一個應用程序並且開始工作。然後,您重新鍵入了上一個應用程序的 URL,並且(猜猜看)在您進入的過程中檢索會話值。

如果您使用無 Cookie 會話,那麼當您第二次訪問該應用程序時,您將被分配一個不同的會話 ID,並且丟失以前的所有狀態。這是無 Cookie 會話的一個典型的副作用。爲了瞭解其原因,讓我們進一步探討無 Cookie 會話的實現。

實現

無 Cookie 會話的實現得益於下列兩個運行時模塊的努力:一個名爲 SessionStateModule 的標準會話 HTTP 模塊,以及一個名爲 aspnet_filter.dll 的可執行文件。後者是一小段 Win32 代碼,它充當 ISAPI 篩選器。HTTP 模塊和 ISAPI 篩選器實現了相同的思想,不同之處在於 HTTP 模塊由託管代碼組成,並且需要 ASP.NET 和 CLR 觸發才能工作。像 aspnet_filter.dll 這樣的傳統 ISAPI 篩選器是由 Internet 信息服務 (IIS) 調用的。二者都截獲在請求處理過程中激發的 IIS 事件。

當新瀏覽器會話的第一個請求進入時,會話狀態模塊讀取 web.config 文件中有關 Cookie 支持的設置。如果 節的 cookieless 屬性設置爲 true,則該模塊生成一個新的會話 ID,通過將該會話 ID 填充到資源名稱前面的相鄰位置來分割 URL,並且使用 HTTP 302 命令將瀏覽器重定向到新的 URL。

當每個請求到達 IIS 入口時(遠遠早於它被移交給 ASP.NET),aspnet_filter.dll 獲得了一個查看它的機會。如果該 URL 將會話 ID 嵌入到括號中,則會提取該會話 ID 並將其複製到一個名爲 AspFilterSessionId 的請求標頭中。然後,重寫該 URL 以使其看起來像原來請求的資源,並且將其釋放。這一次,ASP.NET 會話狀態模塊從請求標頭中檢索會話 ID,並且通過會話-狀態綁定繼續工作。

只要該 URL 包含可用來獲取會話 ID 的信息,無 Cookie 機制就可以很好地工作。正如您稍後將看到的那樣,這會造成一些使用限制。

讓我們研究一下無 Cookie 會話的優缺點。

優點

在 ASP.NET 中,會話管理和表單身份驗證是唯一的兩個在後臺使用 Cookie 的系統功能。通過無 Cookie 會話,您現在可以部署無論用戶的有關 Cookie 的首選項如何都能正常工作的有狀態應用程序。然而,就 ASP.NET 1.x 而言,仍然需要使用 Cookie 來實現表單身份驗證。好消息是,在 ASP.NET 2.0 中,表單身份驗證可以選擇以無 Cookie 方式工作。

另一個經常提出的反對 Cookie 的理由是安全性。這是一個值得予以更多關注的要點。

Cookies 是無活動能力的文本文件,因此,這些文件可能被攻擊者替換或損壞 — 只要他們獲得了對計算機的訪問。真正的威脅並不在於 Cookie 可以在客戶端計算機上安裝什麼,而是在於它們可以向目標站點上載什麼。Cookie 不是程序,並且永遠不會像程序那樣運行;然而,您計算機上安裝的其他軟件可以使用對 Cookie 的瀏覽器內置支持來遠程從事破壞活動。

此外,Cookie 要受到被盜竊的風險。一旦失竊,包含有價值的和私人的信息的 Cookie 就可能將其內容泄露給惡意攻擊者,並且爲其他類型的 Web 攻擊提供便利。總之,通過使用 Cookie,您將自己暴露在本可以消除的風險之中。這是真的嗎?

缺點

讓我們從另一個角度來考察安全性。您是否曾經聽說過會話劫持?如果沒有,則請閱讀一下 TechNet Magazine 文章 Theft On The Web: Prevent Session Hijacking。簡單說來,當攻擊者獲得對特定用戶的會話狀態的訪問時,將發生會話劫持。其實質是,攻擊者竊取有效的會話 ID,並且使用它侵入系統和窺探數據。獲取有效會話 ID 的一種常見方式是竊取有效的會話 Cookie。鑑於此,如果您認爲無 Cookie 會話保護了您應用程序的安全,那您就完全錯了。實際上,對於無 Cookie 會話,會話 ID 直接顯示在地址欄中!請嘗試下列操作:

1.

連接到使用無 Cookie 會話的 Web 站點(例如,MapPoint)並獲得一個映射。此時,該地址存儲在會話狀態中。

2.

抓取 URL(直至頁名稱)。不要包括查詢字符串,但請確保該 URL 包括會話 ID。

3.

將該 URL 保存到文件中,並將該文件複製/發送到另一臺計算機。

4.

在第二臺計算機上打開該文件,並將該 URL 粘貼到新瀏覽器實例中。

5.

只要會話超時仍然有效,就會顯示同一個映射。

通過無 Cookie 會話,可以比以往任何時候都更加容易地竊取會話 ID。

從道德的觀點來看,竊取會話是應該受到譴責的操作,我相信大家會一致認同這一點。但它是否也是有害的?這取決於會話狀態中實際存儲的內容。竊取會話 ID 本身並不會執行超出代碼控制範圍的操作。但是,它可能向未經授權的用戶泄露私有數據,並且使一些壞傢伙能夠執行未經授權的操作。有關如何在 ASP.NET 應用程序中阻止會話劫持的提示,請閱讀 Wicked Code: Foiling Session Hijacking Attempts。(而且,它並不依賴於無 Cookie 會話!)

使用無 Cookie 會話還會引起與鏈接有關的問題。例如,您不能在 ASP.NET 頁中具有絕對的、完全限定的鏈接。如果您這樣做,那麼源自該超鏈接的每個請求都將被視爲新會話的一部分。無 Cookie 會話要求您總是使用相對 URL,就像在 ASP.NET 回發中一樣。僅當您可以將會話 ID 嵌入到 URL 中時,您纔可以使用完全限定的 URL。但是,既然會話 ID 是在運行時生成的,那麼您如何才能做到這一點呢?

下面的代碼中斷了該會話:

<a runat="server" href="/test/page.aspx">Click</a>

要使用絕對 URL,可以藉助於一個小技巧,即,使用 HttpResponse 類上的 ApplyAppPathModifier 方法:

<a runat="server" href=<% =Response.ApplyAppPathModifier("/test/page.aspx")%> >Click</a> 

ApplyAppPathModifier 方法採用一個表示 URL 的字符串作爲參數,並且返回一個嵌入了會話信息的絕對 URL。例如,當您需要從 HTTP 頁重定向到 HTTPS 頁時,該技巧尤其有用。最後,請特別注意,每當您在同一個瀏覽器內部鍵入指向某個站點的路徑時,您都將丟失無 Cookie 會話的狀態。還要請您注意的是,對於移動應用程序,如果設備無法處理專門格式化的 URL,則無 Cookie 會話可能會出現問題。

小結

ASP.NET 中存在無 Cookie 會話的主要原因是用戶(無論出於什麼原因)可能在他們的瀏覽器中禁用了 Cookie。如果您的應用程序需要會話狀態,那麼無論您是否喜歡,您都必須面對這種情況。無 Cookie 會話將會話 ID 嵌入到 URL 中,並且得到了雙重結果。一方面,它們爲 Web 站點提供了一種正確標識發出請求的用戶的方式。然而,另一方面,它們使會話 ID 清楚地顯現在潛在的攻擊者面前,從而使攻擊者可以輕鬆地竊取它並以您的身份進行操作。

要實現無 Cookie 會話,您無需修改自己的編程模型 — 只需在 web.config 文件中進行簡單更改,就可以完成相關工作 — 但是,還要強烈建議您重構您的應用程序,以免在會話狀態中存儲有價值的信息。同時,將會話的生存期縮短至默認的 20 分鐘以內有助於保護您的用戶和站點的安全。

摘抄自微軟

 

這篇文章轉貼是因爲羣裏一些朋友在討論session的時候有爭論,所以我把這篇文章貼上來,以表示cookie和目前版本的session的關係

發佈了47 篇原創文章 · 獲贊 0 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章