軟件開發(fā)過程中安全代碼的七大實(shí)踐
譯文【51CTO.com快譯】眾所周知,軟件的安全性如今已得到了前所未有的重視程度。許多企業(yè)會(huì)將安全性嵌入到應(yīng)用程序的開發(fā)階段。這樣既能有利于整體安全性的遵守,又可以在軟件的不同層面上創(chuàng)建多個(gè)安全性檢查點(diǎn)。本文將通過如下圖所示的各種方面,以實(shí)例的形式,向您展示各種安全代碼的實(shí)踐。雖然主要是以Java為例,但是它們也可以被運(yùn)用到任何其他編程語言上。
1.轉(zhuǎn)義/逃逸輸入(Escape the Input)
所謂轉(zhuǎn)義攻擊是指攻擊者將執(zhí)行命令/查詢,偽裝并嵌入到普通的文字輸入中,通過欺騙應(yīng)用程序的執(zhí)行引擎,而讓其能夠向攻擊者提供各種信息與控制權(quán)。可見,為避免此類攻擊的發(fā)生,我們需要對(duì)用戶的輸入進(jìn)行轉(zhuǎn)義,將其解釋為文字,而非某些命令。同理,我們也需要對(duì)存儲(chǔ)在數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行轉(zhuǎn)義。
試想,如果某用戶在其回帖的文字輸入中帶有JavaScript,那么他就可以試圖從瀏覽器中竊取到Cookie。例如,當(dāng)該回帖的內(nèi)容被呈現(xiàn)在其他用戶的瀏覽器屏幕上時(shí),一旦我們的程序代碼不去轉(zhuǎn)義帖子中的包含的惡意代碼。那么該JavaScript代碼將被執(zhí)行,并為攻擊者提取各種所需的信息與控制權(quán)。以下是帶有潛在風(fēng)險(xiǎn)的數(shù)據(jù)庫查詢代碼,和相應(yīng)的采取了轉(zhuǎn)義措施的Java代碼。
示例:
包含潛在風(fēng)險(xiǎn)的Java代碼
- String query = "SELECT user_id FROM user_data WHERE user_name = '"
- + req.getParameter("userID")
- + "' and user_password = '" + req.getParameter("pwd") +"'";
- try {
- Statement statement = connection.createStatement( … );
- ResultSet results = statement.executeQuery( query );
- }
安全的Java代碼
- Codec ORACLE_CODEC = new OracleCodec();
- String query = "SELECT user_id FROM user_data WHERE user_name = '"
- + ESAPI.encoder().encodeForSQL( ORACLE_CODEC, req.getParameter("userID"))
- + "' and user_password = '"
- + ESAPI.encoder().encodeForSQL( ORACLE_CODEC, req.getParameter("pwd")) +"'";
2.避免將ID作為序列號(hào)
在某些情況下,攻擊者會(huì)設(shè)法超過現(xiàn)有的限制,以獲取更多的信息。例如,某個(gè)API的用戶只被允許查看ID號(hào)為1-100的用戶信息。而如果該系統(tǒng)采用的是以ID為順序的遞增編號(hào)方式,那么我們就可以預(yù)測(cè)到下一個(gè)用戶的序列號(hào)將是101。由此,攻擊者便可以利用這一邏輯上的漏洞,來獲取在其權(quán)限之外的信息。
示例:
包含潛在風(fēng)險(xiǎn)的Java代碼
- String sqlIdentifier = "select TESTING_SEQ.NEXTVAL from dual";
- PreparedStatement pst = conn.prepareStatement(sqlIdentifier);
- synchronized( this ) {
- ResultSet rs = pst.executeQuery();
- if(rs.next())
- long myId = rs.getLong(1);
安全的Java代碼
- // This example is for Oracle
- String sqlIdentifier = "select TESTING_SEQ.NEXTVAL from dual";
- PreparedStatement pst = conn.prepareStatement(sqlIdentifier);
- synchronized( this ) {
- ResultSet rs = pst.executeQuery();
- if(rs.next())
- long myId = rs.getLong(1) + UUID.random();
3.運(yùn)用極簡(jiǎn)主義方法
為了減少攻擊面,系統(tǒng)應(yīng)采用最小的空間使用策略。從本質(zhì)上說,這就意味著系統(tǒng)能夠很好地避免各種權(quán)限的暴露。例如,根據(jù)某項(xiàng)業(yè)務(wù)需求,系統(tǒng)需要使用代碼“HTTP 200”,來響應(yīng)存在著被請(qǐng)求的資源。但是如果我們?yōu)镽EST API提供了get操作,那么就會(huì)增加攻擊者的攻擊面。相反,該系統(tǒng)應(yīng)該只通過HTTP協(xié)議的head方法,來提供有關(guān)現(xiàn)有資源的信息,而不必提供更多的無關(guān)信息。
示例:
包含潛在風(fēng)險(xiǎn)的Java代碼
- //Get is allowed where we need to just check user exist
- http://localhost:8080/User/id/1
安全的Java代碼
- http://localhost:8080/User/id/1
- Head
4.最小特權(quán)原則
讓我們?cè)囅胍粋€(gè)場(chǎng)景:通常,客服部門某個(gè)用戶的常規(guī)訪問權(quán)限是可以訪問訂單數(shù)據(jù)的API。但是為了簡(jiǎn)便起見或是某種原因,系統(tǒng)為其分配了超級(jí)管理員的角色。那么一旦他所處的系統(tǒng)被黑或遭到了帳號(hào)破壞,攻擊者就可以利用他的超級(jí)管理員權(quán)限,來對(duì)該系統(tǒng)發(fā)起一系列的攻擊操作。可見,為了減少攻擊面,我們應(yīng)當(dāng)僅根據(jù)實(shí)際需求,以及既定的角色,來授予目標(biāo)API相應(yīng)的最小訪問權(quán)限,不應(yīng)該在系統(tǒng)中設(shè)置所謂可以訪問所有內(nèi)容的超級(jí)用戶角色。
5.盡可能使用HTTPS或雙向SSL
切勿以最原始的HTTP方式發(fā)布您的網(wǎng)站或是節(jié)點(diǎn)。畢竟如今大多數(shù)瀏覽器都會(huì)對(duì)那些單純的HTTP站點(diǎn)顯示警告。而且,業(yè)界建議針對(duì)集成的端點(diǎn)采用雙向(2-Way)SSL方式,而對(duì)網(wǎng)站或站點(diǎn)通過HTTPS的方式,實(shí)現(xiàn)端到端加密。
不過,由于HTTPS只能保護(hù)了通信信道免受攻擊,卻無法在通道的密鑰發(fā)生泄露時(shí),保護(hù)數(shù)據(jù)。因此,業(yè)界建議使用強(qiáng)大的加密算法,對(duì)各種數(shù)據(jù)記錄先進(jìn)行加密,再通過可信的網(wǎng)絡(luò)予以傳輸。
6.不要使用不安全的或弱的加密算法
如今,隨著計(jì)算機(jī)算力的不斷迭代與提高,弱的密鑰已不再能夠防止那些暴力破解的攻擊手段。一些知名組織甚至將如下不安全的、或弱的加密算法,列入了所謂的“黑名單”。因此您在日常進(jìn)行安全編程時(shí),應(yīng)當(dāng)盡量避免使用到它們。
- SHA-1
- 1024位RSA或DSA
- 160位ECDSA(橢圓曲線)
- 80/112位2TDEA(雙密鑰三重DES)
- 與其他各種舊算法類似,MD5從來都不是政府可以接受的算法。
7.將動(dòng)態(tài)可執(zhí)行代碼(Dynamically Executed Code)列入白名單
如果您有一些代碼是從API或APP的用戶側(cè)傳入的,或者是在用戶輸入之后才生成的,那么為了讓它們能夠作為整體流程的一部分被執(zhí)行,您需要讓系統(tǒng)將這些待執(zhí)行的命令列入白名單。例如,如果系統(tǒng)需要公布某項(xiàng)服務(wù),以列出服務(wù)器上的對(duì)應(yīng)目錄,那么我們就需要將ls或dir之類的命令列入白名單,并轉(zhuǎn)義用戶輸入的標(biāo)志。
小結(jié)
綜上所述,我們從加密、編碼、白名單、最小特權(quán)、以及轉(zhuǎn)義不可信的用戶輸入等方面,為您羅列了日常軟件開發(fā)過程中的七種安全編碼的實(shí)踐示例。希望它們能夠協(xié)助您大幅減少軟件所面臨的各種安全威脅,并提高自身的代碼級(jí)安全態(tài)勢(shì)。
原文標(biāo)題:7 Practical Secure Coding Practices,作者:Awkash Agrawal
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】