在默認(rèn)的JSP、PHP配置中,SessionID是需要存儲在Cookie中的,默認(rèn)Cookie名為:
PHPSESSIONID
JSESSIONID
以下以PHP為例:
你第一次訪問網(wǎng)站時(shí),
服務(wù)端腳本中開啟了Sessionsession_start();,
服務(wù)器會生成一個(gè)不重復(fù)的 SESSIONID 的文件session_id();,比如在/var/lib/php/session目錄
并將返回(Response)如下的HTTP頭 Set-Cookie:PHPSESSIONID=xxxxxxx
客戶端接收到Set-Cookie的頭,將PHPSESSIONID寫入cookie
當(dāng)你第二次訪問頁面時(shí),所有Cookie會附帶的請求頭(Request)發(fā)送給服務(wù)器端
服務(wù)器識別PHPSESSIONID這個(gè)cookie,然后去session目錄查找對應(yīng)session文件,
找到這個(gè)session文件后,檢查是否過期,如果沒有過期,去讀取Session文件中的配置;如果已經(jīng)過期,清空其中的配置
如果客戶端禁用了Cookie,那PHPSESSIONID都無法寫入客戶端,Session還能用?
答案顯而易見:不能
并且服務(wù)端因?yàn)闆]有得到PHPSESSIONID的cookie,會不停的生成session_id文件
取巧傳遞session_id
但是這難不倒服務(wù)端程序,聰明的程序員想到,如果一個(gè)Cookie都沒接收到,基本上可以預(yù)判客戶端禁用了Cookie,那將session_id附帶在每個(gè)網(wǎng)址后面(包括POST),
比如:
GET http://www.xx.com/index.php?session_id=xxxxx
POST http://www.xx.com/post.php?session_id=xxxxx
然后在每個(gè)頁面的開頭使用session_id($_GET['session_id']),來強(qiáng)制指定當(dāng)前session_id
這樣,答案就變成了:能
聰明的你肯定想到,那將這個(gè)網(wǎng)站發(fā)送給別人,那么他將會以你的身份登錄并做所有的事情
(目前很多訂閱公眾號就將openid附帶在網(wǎng)址后面,這是同樣的漏洞)。
其實(shí)不僅僅如此,cookie也可以被盜用,比如XSS注入,通過XSS漏洞獲取大量的Cookie,也就是控制了大量的用戶,騰訊有專門的XSS漏洞掃描機(jī)制,因?yàn)榇罅康?span id="w0dbjnb" class="token constant">QQ盜用,發(fā)廣告就是因?yàn)?span id="sqm7tcn" class="token constant">XSS漏洞
所以Laravel等框架中,內(nèi)部實(shí)現(xiàn)了Session的所有邏輯,并將PHPSESSIONID設(shè)置為httponly并加密,這樣,前端JS就無法讀取和修改這些敏感信息,降低了被盜用的風(fēng)險(xiǎn)。
Cookie在現(xiàn)代
禁用Cookie是?IE6?那個(gè)年代的事情,現(xiàn)在的網(wǎng)站都非常的依賴Cookie,禁用Cookie會造成大量的麻煩。
在Flash還流行的年代,F(xiàn)lash在提交數(shù)據(jù)會經(jīng)常出現(xiàn)用戶無法找到的情況,其實(shí)是因?yàn)镕lash在IE下是獨(dú)立的程序,無法得到IE下的Cookie。
所以在Flash的flash_var中,一般都會指定當(dāng)前的session_id,讓Flash提交數(shù)據(jù)的時(shí)候,將這個(gè)session_id附帶著提交過去
Chrome中使用 Flash沙箱 已經(jīng)解決了cookie的問題,但是為了兼容IE,比如swfupload等flash程序都要求開發(fā)者附帶一個(gè)session_id