摘要:登錄注冊安全風險登錄注冊的風險點主要有四個暴力破解撞庫遍歷注冊用戶批量注冊。引入了驗證碼機制同樣引入了額外的安全風險,比如短信驗證碼的短信炸彈風險圖形驗證碼的可繞過可識別等。
概述
很多技術研發不了解安全,也不重視安全,只有在自己的服務器被黑掉、被掛馬、被脫褲才想起關注安全,但是這個時候,技術架構已經成型、代碼已經在線上穩定運行,再亡羊補牢,改代碼、改策略,往往成本巨大、確收效很低。所以,開發安全,從娃娃抓起。。。
什么是信息安全?信息安全是一個龐大的概念,包含大量不同方向的分支技術,但是都涉及幾個概念:
機密性(Confidentiality),即保證信息在產生、傳輸、存儲、使用等環節不會被泄漏、被惡意竊取。在技術上典型的實現方式就是加密算法。加密算法主要分對稱加密和非對稱加密,對稱加密的加解密密鑰是一樣的,所以在密鑰在存儲、傳輸時會有一定泄漏的風險,但加解密效率會相對高一些。非對稱加密的密鑰不同,各自不會互相影響,所以相對安全,但同樣的,效率會低一些。因此,也隨之產生多種可變的方案,比如,使用對稱加密算法,密鑰通過非對稱加密算法進行加密,可以在效率和安全性上取得一定的平衡。加解密是一門很深的學科,也是信息安全領域一個方向。
完整性(Integrity),即保證信息在產生、傳輸、存儲、使用等環節是真實完整的,不會被惡意篡改。在技術上典型的應用有數字簽名、MD5、校驗和等。其實在網絡協議誕生的初期就已經存在完整性校驗的概念,最典型的就是TCP/IP協議中各種報文的校驗和。而現在互聯網產品,尤其是移動端APP產品很多也都采用簽名的策略,通過將接口傳參、時間戳等進行一次簽名,來防止業務數據在傳輸的過程中被篡改。
可用性(Availability)即保證信息在產生、傳輸、存儲、使用等環節不會被破壞損毀。在技術上典型的應用,安全方面當然就是防DDoS了,DDoS攻擊成本低,效果好,無論大小企業,現在儼然已成為難題之一。DDoS又分很多種,防護起來十分復雜。
以上是信息安全的基本屬性,即CIA屬性。此外,后期還衍生出其他的屬性,如可控性、不可否認性等,總之都是對信息安全概念的補充。
而安全人員的工作,尤其是做企業安全建設的工作,就是圍繞保護數據安全的過程,在事前、事中、事后三個階段,技術上建立掃描、發現、監控、防御、應急、加固等一系列措施,在管理上完善流程、制度、規范,從而使以上幾個安全屬性得到保障。
概念說了很多,落地到實際是什么樣子呢,簡單總結了一個安全架構圖,比較全的涵蓋了企業安全建設的要點。
以上是宏觀層面,那具體到每個技術研發同學的身上,最常見的就是對各種安全漏洞、安全風險的處理修復。下面介紹開發過程中常見的安全風險點。
1.SQL注入sql注入危害很大,也很常見,可以導致企業數據直接被泄漏出去。典型的sql注入漏洞是這樣產生的:
void doPost(HttpServletRequest request, HttpServletResponse response){
JdbcConnection conn = new JdbcConnection();
final String sql = "select * from product where pname like "%” + request.getParameter("name") + "%"";
conn.execqueryResultSet(sql);
}
在sql中直接拼接了字符串,導致用戶可以通過插入惡意代碼來控制sql執行。比如這樣:
select * from product where pname like ‘%name%’;
qudian’;drop database;//
就變成了
那么怎么防御sql注入呢?最簡單正確的方式就是預編譯。為什么用預編譯,首先要了解sql注入的原理:sql注入產生在數據庫的編譯階段,拼接字符串時,sql和用戶可控的數據部分拼接到一起,一次發送到數據庫,數據庫編譯時就會把sql指令和數據編譯到一起,如果用戶可控的數據部分有非法的命令,也會被數據庫編譯執行,這樣就產生了sql注入。而預編譯的方式,sql和用戶可控的部分是分兩次發給數據庫的,第一次發sql指令,也就是上個例子的select * from product where pname like ‘%name%’;,數據庫收到后先進行編譯,第二次再發送數據qudian’;drop database;//,此時數據庫不會重新編譯第一次收到的指令,而是把指令和數據區分開,這樣不論用戶輸入的是什么非法數據,數據庫都會認為是數據部分,也就不會產生sql注入了。上面的過程通過抓包可以看到。
預編譯的簡單寫法:
正常查詢 conn = createConnection(); String sql = “select name,password from manager where name=? and password=?"; stat = conn.prepareStatement(sql); stat.setString(1, name); stat.setString(2, password); stat.executeQuery(sql); 模糊查詢 conn = createConnection(); String sql = "select * from table where url like ?"; stat = con.prepareStatement(sql); String data="data"; stat.setString(1, "%"+data+"%"); stat.executeQuery(sql);2.跨站腳本攻擊XSS
很多人不重視XSS,覺得XSS沒有大危害,“只是能彈個窗有什么用?”但實際XSS的危害甚至不弱于遠程代碼執行等。平時常見的XSS的危害場景:
盜取cookie
讀取用戶隱私
蠕蟲
DDoS
釣魚
鍵盤記錄
執行代碼
等等
XSS是怎么插的?舉個簡單的例子。
通常正常的表單是這樣的:
`` www.qufenqi.com/1.html?name=abc
但是現實總是和理想有差距。黑客通常會這樣填充表單:
www.qufenqi.com/1.html?name=abc”/>//
這樣就造成了XSS,可以彈出一個窗口。
這種現象是產生的原因是由于服務端對用戶的輸入沒有做任何處理,因此在瀏覽器渲染時,用戶輸入的js代碼就會執行。既然知道了原因,就不難修復,只要讓瀏覽器渲染時js代碼不會執行就可以了。最完美的解決XSS的方案:
html標簽之間:html實體編碼;
html屬性里:html屬性編碼HH; (以開頭,HH則是指該字符對應的十六進制數字,分號作為結束符);
javascript里:javascrpt編碼xHH (以 x 開頭,HH則是指該字符對應的十六進制數字);
css樣式里:css編碼HH (以 開頭,HH則是指該字符對應的十六進制數字);
url里:url編碼%HH(以 % 開頭,HH則是指該字符對應的十六進制數字);
Json里:response.setContentType(“appliaction/json”);
富文本里:過濾。
由于富文本中有需要用戶提交一些html、js、css標簽,因此不能直接處理,建議除可能必需保留的標簽外,過濾其他危險標簽。
dynsrc、src、action、href、background、bgsound、lowers、value、onmouse*
applet、blink、frameset、iframe、object、base、body、head、layer、style、basefont、embed、html、link、title、bgdound、frame、player、meta、script
vbscript、ms-its、firefoxurl、javascript、shtml、mocha、data、livescript
解決XSS通常有兩種誤區:
第一個,喜歡用過濾的方式。但是過濾不能完全避免XSS,通過轉義等很多方式可以繞過過濾的方法。比如這是正常的XSS語句,可以通過過濾關鍵字來解決。
``` 但是我把它變換一種形式,依然能夠達到效果,比如這樣:
`
第二個,不論XSS輸出在哪,都用一種方式轉義。有時候開發會寫一個全局的轉義方法,之后不論什么時候在哪出現XSS,都調用這個方法,雖然暫時可行,但時間長了容易引入dom xss,不是一個完美的方案。
首先一個圖簡單明了的展現了CSRF的過程
簡單的說就是在用戶的某個網站cookie有效時,誘使用戶去請求黑客構造好的惡意請求,就能在神不知鬼不覺的情況下進行攻擊。一個發生過的經典例子,某網站后臺管理員更改密碼的功能,沒有校驗目前使用的密碼,可以直接設置新的管理員密碼。操作請求的參數只有一個新的密碼,所以構造鏈接http://xxx.com/updatepass?new...,誘使管理員去請求,就可以默默的改變管理員密碼。
下一個問題就是如何誘使受害者去主動請求惡意的鏈接,方式多種多樣,比如在自己的網站上插入這個鏈接,讓用戶訪問你的網站;在論壇里插入外鏈圖片,圖片鏈接是惡意的鏈接,這些都可以。除此之外,CSRF結合其他漏洞更能達到驚喜的效果,前幾年知名的新浪微博蠕蟲刷粉絲,可以短時間增長大量的粉絲,就是CSRF和XSS在一起的功效。
那么防御CSRF的方案呼之欲出,目前主流的兩種方案:1.讓黑客不能偽造惡意的請求;2.校驗來源的請求是不是用戶正常觸發的。第一點,通常使用token校驗。第一步,用戶登錄時,服務端生成token,保存在session中。第二步,token可以放在表單中或者http請求頭中。 第三步,客戶端帶著token發請求給服務端,服務端校驗token。這樣通過客戶端和session中的token比較,就可以得知請求是否合法。由于token是隨機字符串,黑客無法獲取,也就無法構造請求了。第二點,校驗referer,這是一個比較簡單的實現方式,通過校驗referer白名單也可以起到防御CSRF攻擊的作用。但是這里有個坑,很多開發寫正則來取referer,有時候就會造成各種繞過的姿勢,比如www.qufenqi.com.baidu.com這樣。因此在寫正則的時候一定要注意。
登錄注冊的風險點主要有四個:暴力破解、撞庫、遍歷注冊用戶、批量注冊。
首先登錄,三個必備的要素:用戶名、密碼、驗證碼。驗證碼是手機短信驗證碼或者圖形驗證碼。通過手機短信驗證碼既可以識別用戶身份,為風控提供基礎,又可以防護暴力破解、撞庫等批量的攻擊行為。圖像驗證碼則可以人機識別,防護暴力破解、撞庫。引入了驗證碼機制同樣引入了額外的安全風險,比如短信驗證碼的短信炸彈風險、圖形驗證碼的可繞過、可識別等。此外,也可以加入一些高級的安全策略,輔助分析防護安全風險,如異地登錄提醒、記錄非常用設備登錄、校驗用戶歷史行為。
這里簡單說下校驗用戶歷史行為。很多產品在設計需要校驗身份的場景時,沒有完全的考慮各類安全風險,一個常見的例子就是通過短信驗證碼來找回密碼,產品理想中的場景是短信驗證碼只能用戶自己收到,所以可以確認用戶身份,但實際有很多不可控的因素,比如,用戶手機丟失的情況。因此,在注冊登錄點需要綜合考慮各種情況。
剛才提到圖形驗證碼,圖形驗證碼如果設計開發的不當就會形同虛設。一個完善的圖形驗證碼流程是這樣的:
1.客戶端發起一個請求。
2.服務端響應并創建一個新的SessionID同時生成一個隨機驗證碼。
3.服務端將驗證碼和SessionID一并返回給客戶端。
4.客戶端提交驗證碼連同SessionID給服務端。 5.服務端驗證驗證碼同時銷毀當前會話,返回給客戶端結果。
如果整個流程中的某個環節處理不當,則會產生各種問題:
1.驗證碼不過期,可重復使用。這是比例最大的驗證碼安全風險,產生這種現象的主要原因是驗證碼的刷新是在前端進行,服務端的功能只有接收驗證碼判斷對錯,并沒有sessionid的機制,這樣只要攔截請求每次使用這個驗證碼重新發包,就可以繞過驗證碼的策略做各種攻擊嘗試。正確的做法是每次校驗驗證碼之后,服務端要重新生成驗證碼。
2.驗證碼輸出到客戶端。這種問題也很常見,很多驗證碼的邏輯是在請求驗證碼時,服務端不只返回驗證碼圖片,還返回圖片里的內容,這樣通過抓取返回中的驗證碼內容字段就可以繞過驗證碼的人機識別過程。爭取的做法是服務端返回時,不要返回驗證碼內容,直接返回一張圖片即可。
3.驗證碼前端生成,前端校驗。這里涉及安全的一個原則:永遠不要信任用戶端的輸入。所有前端的代碼都是可以被用戶修改的,因此如果在前端做驗證碼處理,黑客則可以通過修改前端代碼自己生成,自己校驗,完全繞過驗證碼的邏輯。
4.驗證碼可以被識別。這是目前驗證碼的一個難題。現在圖像識別的技術非常成熟,前端的數字字符驗證碼,即使增加了背景、干擾、粘連等措施,也可以被輕松識別。因此驗證碼技術現在逐漸發展成通過用戶行為識別和找不同來做人機識別。比如滑動驗證碼、12306那類的驗證碼。
5.第三方系統的安全很多產品避免不了和第三方產品的互相調用,但是在調用過程中如果不注意安全控制,很容易因為第三方系統的安全問題,導致自己的安全風險。以前遇到過一個例子,某電商網站擴展二手回收業務,和某二手回收網站合作,會將自己的一些用戶信息傳給二手回收的系統,結果因為對方的安全做的不夠完善,導致自己的大量用戶信息被泄漏。造成了很嚴重的影響。但是第三方的系統安全我們是控制不了的,因此我們只能互相調用的接口傳輸過程中加入安全策略。通常有以下幾種做法:
1.IP訪問控制(白名單):這個是必需的,通常此類接口調用都不涉及很多的范圍,都是雙方之間的調用,需要做訪問控制來限制惡意來源的訪問掃描。
2.接口簽名:簽名也是現在普遍的做法,通過簽名可以確定接口傳輸的信息沒有被惡意篡改。簽名的簡單邏輯是:簽名串=MD5(明文參數&密鑰),然后將簽名串作為參數與原來的參數一起發給服務端。服務端收到明文參數后,同樣進行一次MD5(明文參數&密鑰),并于收到的簽名串做比較,即可校驗是否被篡改。現在的簽名技術已經相對完善。
3.敏感數據加密:敏感數據一定不要直接明文在互聯網傳輸,要通過加密。加密算法可以選擇對稱加密和非對很加密,加密算法可以選用對稱加密的AES或者非對稱加密的RSA,或者二者綜合使用。
簡單的介紹了線上常見的幾種安全風險,接下來說說幾點安全基本的原則,也是各種安全方案的思想。通過這幾個原則可以擴展出很多成熟的安全方案。
1.不要信任用戶的輸入:從用戶端傳過來的任何數據都是不可信的無論是請求頭還是請求體,都是可以隨便更改的。因此,這里邊可能包含大量的惡意代碼。用戶傳過來的數據一定要做一些關鍵的過濾、校驗。對參數的類型、長度等一定要有預期,不符合預期的要做處理。此外,關鍵的算法、邏輯操作和數據不要在js中處理。js是可以隨意更改的。一個典型的例子,大轉盤抽獎一般是通過js實現,于是中獎的規則也在js中一起實現,js判斷之后直接將中獎結果通知服務端,這樣黑客就可以通過js隨意控制抽獎的過程和結果了。
2.合理利用加密、簽名:加密和簽名是安全策略中不可或缺的一部分。關鍵敏感的數據和接口一定要做加密和簽名,加密和簽名算法的選擇又是一個龐大的話題,以后可以多帶帶細說。
3.關鍵操作的身份認證:關鍵操作不做身份認證就好像不問別人是誰就讓他進你家門。在做身份認證時注意的幾個要點:第一不要直接通過傳參數來判斷身份,比如userid,這是可以隨意更改的;第二不要通過cookie中的某個字段判斷身份,cookie中的信息也是可以隨意更改的。正確的做法是通過session來獲取用戶身份。
4.邏輯步驟:有時候有些邏輯步驟本可以一個步驟完成,卻分成兩個步驟,這種情況就有可能繞過第一個步驟直接判斷第二個。舉個簡單的例子,登錄時候輸入用戶名、密碼、短信驗證碼,有的開發會先通過一個請求判斷短信驗證碼是否正確,之后根據結果再發送請求。這時如果直接發送第二個請求就可以繞過短信驗證碼的校驗,產生安全風險。因此,無論需要檢驗的參數數量有多少,都需要在一個步驟中做好所有的校驗,之后再返回最終結果。
5.策略一致性:現在的產品大多有多個平臺,比如web端和app端。此時這兩個平臺的安全策略需要完全一致,才不會有疏漏。舉一個以前遇到的例子,XSS的處理,在web端做輸入過濾,在app端做輸出轉義,此時多帶帶在兩個平臺都無法XSS,但是如果在app端輸入,在web端輸出,就恰好繞過兩個平臺的安全策略,最終成功XSS。因此,多個平臺的產品,需要多個平臺保持一致的安全策略才行。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/11467.html
摘要:注釋是代碼中最常見的組成部分它們是另一種形式的文檔也是程序員最后才舍得花時間去寫的但是對于代碼的總體可維護性而言注釋是非常重要的一環打開一個沒有任何注釋的文件就好像趣味冒險但如果給你的時間有限這項任務就變成了折磨適度的添加注釋可以解釋說明代 注釋是代碼中最常見的組成部分.它們是另一種形式的文檔,也是程序員最后才舍得花時間去寫的.但是,對于代碼的總體可維護性而言,注釋是非常重要的一環.打...
摘要:在登錄后臺時也是必須認證才行。使用這種總比粗暴的限制訪問來保護安全要高效的多,一切都是為了自動化,為了提高生產率。總結本文主要學習使用這個神器來做,并學習了如何使用集成進程序中。我司最近需要一名伙伴一起共同航海去,有興趣速來。 說明:本文主要研究利用Duo來實現雙重認證,Two-Factor Authentication就是除了username-password這種登錄認證之外,還使用...
閱讀 1397·2021-09-22 15:43
閱讀 2647·2021-09-22 15:32
閱讀 4926·2021-09-22 15:11
閱讀 2559·2019-08-30 15:55
閱讀 2910·2019-08-30 15:54
閱讀 1200·2019-08-30 15:44
閱讀 1474·2019-08-29 13:26
閱讀 1053·2019-08-29 12:54