如何实现一个安全的Web登陆
綜述:
待 Update:QUIC, SSO, HSTS等協(xié)議研究,SHA-1 可破解
總結(jié): 沒有絕對的安全,能不自己做就不自己做, 要么 openID(不了解), 要么OAuth(推薦QQ & Github)
本文不考慮鍵盤記錄器等養(yǎng)毒行為, 本文不考慮堆棧溢出, exploit, SQL注入等。 單純談?wù)撈虻顷憰掃^程
思維養(yǎng)成key: 時間, 信任
無解問題: CSRF, 中間人攻擊(有應(yīng)對方案,但沒有根本解決的方案)
SSL必加, 客戶端加密可選, localStorage 存 token(CSRF), 指紋ID:UUID(Java),cookie 設(shè)計Chrome Dev參考網(wǎng)站猜測大致保存用戶名,session, jsessionid, uuid, token(瀏覽器不支持localStorage), Hm_lvt_siteid(記錄訪客當(dāng)前訪問序列的開始時間,如果沒有設(shè)置這個cookie,則訪客為新訪客。當(dāng)本次訪問是一個新的訪問開始時,更新該cookie為當(dāng)前時間.), Hm_lpvt_siteid(當(dāng)前瀏覽頁面時的時間,每次瀏覽時設(shè)置該cookie為當(dāng)前時間)等
正文
09年老5則
加密單向并且強(qiáng)壯(MD5我100個不推薦, 看刷ctf的整天口算md5玩, 看開頭,所以推薦 SHA2)
密碼長度強(qiáng)制長
密碼字符無限制, 至少滿足ascii(出開頭結(jié)束空格)
不要給用戶發(fā)送他的密碼(VMware就這么蠢比過) IMAP 應(yīng)用,中間人攻擊 between the mail client and GMail
- Anyone who had access to the network or SMTP systems involved in the hand-off chain between VMware’s systems and Google.
- Anyone who has administrative access to Google’s email systems, including the eternal GMail backups.
- Anyone capable of compromising the integrity of Google’s systems.
- Anyone capable of compromising the integrity of my laptop.
- Anyone who gains access to a public machine I was using after I forgot to log out of GMail.
OpenID 不適合作為安全的關(guān)鍵部分, 但大部分適用
忠告: Don’t implement your own authentication system unless you absolutely have to
總結(jié): 贊忠告,為啥不試試OAuth 2.0 操作之類的?我選 github & qq sdk
初步探索
token, user_id, track ip
產(chǎn)生一個隨機(jī)token發(fā)到客戶端作為cookie, 這個cookie 與 服務(wù)器做出匹配來確定用戶
除非實現(xiàn)session策略或者網(wǎng)站分布在集群之類的,不要用數(shù)據(jù)庫存儲session
hash + salt 密碼加密, 打算加鹽(一個用戶一種鹽)防彩虹表?
Wiki
認(rèn)證分兩部分: 登陸表單, per-request-check
會話劫持
方式:
猜測
fixation: xss, 網(wǎng)絡(luò)嗅探
應(yīng)對:
cookie設(shè)置 HTTP only。 可仿瀏覽器偽造,仿 js 注入
樓上那個, 不好意思,可解
登陸不僅僅依賴sessionid
session 時間, client指紋(一般是設(shè)備信息決定)變化, 登出請求 時銷毀cookie, 清理session
Note: 指紋舉例 fingerprint=hashhmac(′sha256′,_SERVER[‘HTTP_USER_AGENT’], hash(‘sha256’, $_SERVER[‘REMOTE_ADDR’], true));
SSL 是最好的仿白文傳送, 對比而言, 別用客戶端加密這個方法(因為劫持了就相當(dāng)于拿到了加密,加密本身也就沒了效果)
所以要加密就在server端加密
鹽的生成可以從加密來挑字符,關(guān)于鹽的長度: Even 4 random bytes of salt will increase the complexity of a rainbow table attack by a factor of 4 billion.
SSL 是必須的,無論如何這個都必須
Bcrypt
Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power…. Cryptotheoretically, this is no stronger than the standard Blowfish key schedule, but the number of rekeying rounds is configurable; this process can therefore be made arbitrarily slow, which helps deter brute-force attacks upon the hash or salt.
SSL安裝: 自己做個證書強(qiáng)迫用戶裝(又是12306), 買(阿里送了個1000元一年的, 想想都貴), let ‘s encrypt(免費 且 賊棒,crontab設(shè)置個90天內(nèi)翻新就行了)
爆力攻擊減速, 如果失敗, 等待一定時間后返回失敗(考慮用戶體驗取舍,建議可加)
慣用行為: 。。。。感覺這個太他媽難, 就是類似twitter那樣換個瀏覽器換個ip換個設(shè)備立馬曉得然后通知你
驗證碼(CAPTCHA): 這是個用戶體驗很差的東西,想想12306? 總之做的有點意思或者大氣上檔次才行
休息一下
攻擊:堆棧溢出。 解決:防偽式編程, 驗證和過濾惡意輸入
攻擊:留言,打倒GCD這種神奇操作。 解決: 茍利國家生死以,豈因福禍避趨之。 給他過掉
錯誤:仿debug模式報異常等。 解決:控制好異常的邊界
初步設(shè)計Cookie
Cookie 設(shè)計, 三個東西:
用戶名
登陸序列, 僅當(dāng)強(qiáng)制用戶輸入口令時更新
登陸 token
僅一個登錄Session內(nèi)有效
新的登錄Session會更新它
登錄Token是單實例登錄 Singleton
當(dāng)前兩者正確,第三者卻不正確時(有人盜用更新了token)用戶回來訪問時不對,系統(tǒng)便清除登陸序列和token令cookie失效
重要操作必須輸入口令, 比如支付, 改密信息之類的, 不能因cookie直接操作(大概想防XSS?)
密保設(shè)定私人信息(比如你爸媽叫啥)有點白癡,因為可以社工之類的
郵件重置較為安全, 根據(jù)用戶(uuid,timestamp,token等)生成MD5 url,并設(shè)定操作權(quán)限時間。
系統(tǒng)操作封IP之類的, 凍結(jié)賬戶這種操作由用戶決定, 少做讓用戶反感的事
重點:必看 Cookie 參數(shù)詳解
CSRF Token
Token 保存
csrf token 保存在瀏覽器的localStorage, 不是cookie
請求時利用 csrf token 作為鹽值, 每次請求的時候使用CsrfToken作為鹽值對參數(shù)進(jìn)行Md5簽名,網(wǎng)關(guān)從請求的Cookie中取出userToken并AES解密出CsrfToken,再進(jìn)行驗簽。用戶退出或者userToken時效的時候都會主動從LocalStorage中清除CsrfToken,從cookie中清除Token和用戶信息,任何需要訪問用戶登錄態(tài)的數(shù)據(jù)因為都需要加密,所以首先會判斷CsrfToken是否存在,不存在直接跳登錄頁了。
這樣一來, 鹽值不參與請求, 只是加密用
短信檢測考慮成本必加時限和圖片驗證
Token 可選位置
驗證 HTTP Referrer 字段;(仿盜圖用也不錯,但可以手工修改,所以不是好方案)
在請求地址中添加 token 并驗證, 表單生成帶token
在 HTTP 頭中自定義屬性并驗證。
總結(jié): CSRF 難解,可以說各有利弊,換句話說差不多就是解不了
Token 必知必會
- Note: Ajax 同源, CORS 跨源, JSONP
Demo
數(shù)據(jù)結(jié)構(gòu)設(shè)計: 用戶數(shù)據(jù) 和 認(rèn)證分開存儲, 從而便于認(rèn)證擴(kuò)展
驗證成功的token要更新
客戶端加密公開, 所以要加密就加鹽,讓他推也難受
實例示范:
瀏覽器主要完成以下工作:
獲取用戶輸入的用戶名及密碼
通過輸入的用戶名和密碼,進(jìn)行哈希,得到瀏覽器端密文
將用戶名和密文提交給后端
后端驗證:
獲取前端提交的用戶名及瀏覽器端密文
根據(jù)用戶名,在數(shù)據(jù)庫中查詢出對應(yīng)的鹽 id
通過鹽 id 取出對應(yīng)的鹽,再通過用戶名、瀏覽器端密文和鹽算出后端密文
根據(jù)用戶名和后端密文到用戶表查詢,如果有結(jié)果,則表明登錄信息正確,返回給瀏覽器登錄成功的響應(yīng)
生成新的鹽,算出新的后端密文,并將兩者更新到數(shù)據(jù)庫中
前面返回給用戶成功登錄的響應(yīng)之后,調(diào)用了更新鹽和密文的方法,該方法具體流程如下:
生成并存儲新鹽
根據(jù)新鹽、用戶名和瀏覽器端密文,生成新的后端密文
存儲后端密文到用戶信息表
數(shù)據(jù)存儲這塊,使用了 Waterline 這個 ORM 中間件使用它的目的主要是為了將用戶信息和鹽存儲到不同的地方。本例中將鹽用 sails-disk 存儲到了文件中,用戶信息用 sails-mongo 存儲到了 MongoDB 中。
后記
XSS & CSRF , SSRF 不考慮
盜用 cookie ,獲取敏感信息。
利用植入 Flash ,通過 crossdomain 權(quán)限設(shè)置進(jìn)一步獲取更高權(quán)限;或者利用Java等得到類似的操作。
利用 iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊)用戶的身份執(zhí)行一些管理動作,或執(zhí)行一些一般的如發(fā)微博、加好友、發(fā)私信等操作。
利用可被攻擊的域受到其他域信任的特點,以受信任來源的身份請求一些平時不允許的操作,如進(jìn)行不當(dāng)?shù)耐镀被顒印?/p>
在訪問量極大的一些頁面上的XSS可以攻擊一些小型網(wǎng)站,實現(xiàn)DDoS攻擊的效果。
防御: 過濾; Http制定頭類型, 避免被解析為html
TLS MITM 這玩意能解?
參考鏈接:
https://www.zhihu.com/question/20744215
https://www.v2ex.com/t/161520
一般能防MITM的要具有以下特征:
1、握手加密而且具有可信CA(SSL、TLS之類,CNNIC和WoSign就不點評了)或擁有預(yù)協(xié)商密鑰(L2TP)
2、加密方法足夠強(qiáng)大(AES、CHACHA20之類,RC4和SM2就不點評了)
綜上,一般情況下,以下的協(xié)議是安全的:
1、HTTPS(排除RC4、3DES算法,排除CNNIC、WoSign的CA證書)
2、OpenVPN(基于TLS,只要你能連上就是安全的)
3、L2TP Over IPSec(必須要Over IPSec,沒了就沒加密了)
4、IKEv2(基于TLS和可信CA發(fā)的證書,安全性比OpenVPN還好)
5、SSTP(基于TLS和可信CA發(fā)的證書,安全性和IKEv2相同,穩(wěn)定性加強(qiáng),用443端口)
6、ShadowSocks(基于N+1種加密算法,只要你不選RC4或RC4-MD5算法就是安全的)
7、任何用SSL Stream過又驗證CA甚至客戶端證書的TCP連接(UDP大家都懂,DNS什么的)
總結(jié)
以上是生活随笔為你收集整理的如何实现一个安全的Web登陆的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 航天恒星系统集成项目组
- 下一篇: 有关学习方面的资料如何进行打印