2013-11-22 32 views
2

我們不久前將我們的網站移動到新的託管服務器,並且偶爾會遇到人們無法註銷的問題。不確定這與主機環境或代碼更改有什麼關係。通過Set-Cookie註銷失敗

這是相關位的Wireshark日誌 - 全部發生在同一個TCP流中。從瀏覽器

  1. 註銷請求(注意驗證Cookie):

    GET /cirrus/logout HTTP/1.1 
    
    Host: subdomain.domain.com 
    
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 
    
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
    
    Accept-Language: en-US,en;q=0.5 
    
    Accept-Encoding: gzip, deflate 
    
    Referer: http://subdomain.domain.com/cirrus/CA/Admin/AccountSwitch 
    
    Cookie: USER.AUTH=AOvDEjH3w6xIxUC0sYNOAQR5BZ7pPmEF0RMxqohERN87Ti03Eqxd7rQC/BveqmaszmFg8QoSonP+Z+mtQQivKpvloFsQYretYKR8ENubj+moUBF479K5e4albKxS9mBEWT5Xy/XCnEyCPqLASGLY09ywkmIilNU1Ox4J3fCtYXHelE/hyzuKe9y3ui5AKEbbGs3sN9q1zYjVjHKKiNIGaHvjJ2zn7ZUs042B82Jc9RHzt0JW8dnnrl3mAkN1lJQogtlG+ynQSCyQD8YzgO8IpOnSXLJLaCMGMQcvSyX4YKJU/9sxgA5r5cZVCkHLsReS3eIJtXoxktMO6nxVZJY6MX1YwuJOgLRQvwBy9FFnQ6ye 
    
    X-LogDigger-CliVer: client-firefox 2.1.5 
    
    X-LogDigger: logme=0&reqid=fda96ee5-2db4-f543-81b5-64bdb022d358& 
    
    Connection: keep-alive 
    
  2. 服務器響應。它清除cookie值,並重定向

    HTTP/1.1 302 Found 
    
    Server: nginx 
    
    Date: Fri, 22 Nov 2013 14:40:22 GMT 
    
    Content-Type: text/html; charset=utf-8 
    
    Content-Length: 124 
    
    Connection: keep-alive 
    
    Cache-Control: private, no-cache="Set-Cookie" 
    
    Location: /cirrus 
    
    Set-Cookie: USER.AUTH=; expires=Fri, 22-Jul-2005 14:40:17 GMT; path=/cirrus 
    
    X-Powered-By: ASP.NET 
    
    X-UA-Compatible: chrome=IE8 
    
    
    
    <html><head><title>Object moved</title></head><body> 
    
    <h2>Object moved to <a href="/cirrus">here</a>.</h2> 
    
    </body></html> 
    
  3. 瀏覽器遵循重定向,但與舊Cookie值:

    GET /cirrus HTTP/1.1 
    
    Host: subdomain.domain.com 
    
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 
    
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
    
    Accept-Language: en-US,en;q=0.5 
    
    Accept-Encoding: gzip, deflate 
    
    Referer: http://subdomain.domain.com/cirrus/CA/Admin/AccountSwitch 
    
    Cookie: USER.AUTH=AOvDEjH3w6xIxUC0sYNOAQR5BZ7pPmEF0RMxqohERN87Ti03Eqxd7rQC/BveqmaszmFg8QoSonP+Z+mtQQivKpvloFsQYretYKR8ENubj+moUBF479K5e4albKxS9mBEWT5Xy/XCnEyCPqLASGLY09ywkmIilNU1Ox4J3fCtYXHelE/hyzuKe9y3ui5AKEbbGs3sN9q1zYjVjHKKiNIGaHvjJ2zn7ZUs042B82Jc9RHzt0JW8dnnrl3mAkN1lJQogtlG+ynQSCyQD8YzgO8IpOnSXLJLaCMGMQcvSyX4YKJU/9sxgA5r5cZVCkHLsReS3eIJtXoxktMO6nxVZJY6MX1YwuJOgLRQvwBy9FFnQ6ye 
    
    X-LogDigger-CliVer: client-firefox 2.1.5 
    
    X-LogDigger: logme=0&reqid=0052e1e1-2306-d64d-a308-20f9fce4702e& 
    
    Connection: keep-alive 
    

有什麼明顯的在Set-Cookie頭可能丟失防止瀏覽器刪除cookie?

要改變現有的cookie的值,下面的cookie參數必須匹配:

  • 路徑

名和路徑explecitely設置,域不是。這可能是問題嗎?

編輯:由於有人問過爲什麼在過去設置過期日期,因此需要更多背景。 這是對AppHarbor安全插件的一個小修改:https://github.com/appharbor/AppHarbor.Web.Security 修改是包含cookie的路徑。請在這裏找到修改的方法註銷:

public void SignOut(string path) 
    { 
     _context.Response.Cookies.Remove(_configuration.CookieName); 
     _context.Response.Cookies.Add(new HttpCookie(_configuration.CookieName, "") 
     { 
      Expires = DateTime.UtcNow.AddMonths(-100), 
      Path = path 
     }); 
    } 

在過去的到期日期由AppHarbor插件完成,是常見的做法。見http://msdn.microsoft.com/en-us/library/ms178195(v=vs.100).aspx

+1

放棄cookie服務器端而不是客戶端不是更明智嗎? – flup

+0

這樣做實際上更安全,持續的會話只會暴露風險。 – zinking

回答

1

在猜測我會說歷史到期日期導致整個Set-Cookie行被忽略(爲什麼設置一個cookie過期8年前?)。

expires=Fri, 22-Jul-2005

+0

嗨,在內部,它使用AppHarbor安全插件來執行cookie處理。我猜它遵循這個指導原則:http://msdn.microsoft.com/en-us/library/ms178195(v=vs.100).aspx,但也清空cookie值,如果這是不榮幸 – michael81

1

我們有問題,在過去刪除cookies和肯定的域名和路徑必須與您正在試圖刪除cookie的域和路徑相匹配。

嘗試在HttpCookie中設置正確的域和路徑。

1

偉大的問題,和優秀的筆記。我最近也遇到過這個問題。

有一個故障安全的方法來此,超越你應該已經這樣做:在過去

  • 集過期。
  • 設置路徑域。
  • 將假數據放入要刪除的cookie中!

Set-Cookie: USER.AUTH=invalid; expires=Fri, 22-Jul-2005 14:40:17 GMT; path=/cirrus; domain=subdomain.domain.com

故障安全的方法是這樣的:

特殊字符串添加到所有的cookies,在最後。除非存在該字符串,否則拒絕cookie並強制重置它。例如,所有新的Cookie必須是這樣的:

Set-Cookie: USER.AUTH=AOvDEjH3w6xIxUC0sYNOAQR5BZ7pPmEF0RMxqohERN87Ti03Eqxd7rQC/BveqmaszmFg8QoSonP+Z+mtQQivKpvloFsQYretYKR8ENubj+moUBF479K5e4albKxS9mBEWT5Xy/XCnEyCPqLASGLY09ywkmIilNU1Ox4J3fCtYXHelE/hyzuKe9y3ui5AKEbbGs3sN9q1zYjVjHKKiNIGaHvjJ2zn7ZUs042B82Jc9RHzt0JW8dnnrl3mAkN1lJQogtlG+ynQSCyQD8YzgO8IpOnSXLJLaCMGMQcvSyX4YKJU/9sxgA5r5cZVCkHLsReS3eIJtXoxktMO6nxVZJY6MX1YwuJOgLRQvwBy9FFnQ6ye|1386510233; expires=Fri, 22-Jul-2005 14:40:17 GMT; path=/cirrus; domain=subdomain.domain.com

注意的變化:存儲在USER.AUTH那極長的字符串|1386510233結束,這是當下的Unix紀元時,cookie中設定。

這爲cookie解析添加了一個簡單的額外步驟。現在,您需要測試|的存在並放棄unix時代,除非您知道cookie何時設置。爲了使它更快,你可以檢查string[length-10]==|而不是解析整個字符串。按照我的方式,我將字符串拆分爲|,並在分割後檢查兩個值。這繞過了兩部分的解析過程,但是這個方面是語言特定的,當涉及到您選擇的策略時,這只是優先考慮的。如果您打算放棄該值,請檢查您希望|所在的具體索引。

未來,如果您再次更改主機,您可以測試該unix時期並拒絕比某個時間點早的cookie。這最多會爲您的Cookie處理程序添加兩個額外的進程:刪除|unixepoch,如果需要,檢查何時該拒絕Cookie,如果您再次更改主機。這會將約0.001s增加到頁面加載,或更少。與客戶服務失敗和大規模腦損傷相比,這是值得的。

您的新Cookie策略允許您立即拒絕所有沒有|unixepoch的Cookie,因爲您知道它們是舊餅乾。是的,人們可能會抱怨這種做法,但這是真正瞭解cookie的唯一方法。你不能依靠客戶端來提供有效的cookie。除非要存儲大量數據,否則無法保存每個cookie的記錄。如果您將每個cookie都進行倉儲並每次檢查一次,那麼可以在此策略中將0.01s添加到頁面載荷,而將0.001s添加到此策略中,因此倉儲路線不值得。

另一種方法是使用USER.AUTHENTICATION而不是USER.AUTH作爲新的cookie值,但這可能更具侵入性。當您再次更換主機時,您無法從上述內容中獲益。

祝您過渡。我希望你能理清這一點。使用上述策略,我能夠做到。

+1

非常感謝。似乎是最好的解決方案。我希望找出cookie處理的方式有什麼問題 - 但是從我所看到的情況來看,某些瀏覽器對此有不同的解釋。你的失敗安全方法defo應該工作。 – michael81

+0

我非常高興這個策略對你有幫助,你明白爲什麼我的方法有優點。它不一定是「漂亮」的,但它總是有效的! – digitalextremist