前言 我們的API接口都是提供給第三方服務(wù)/客戶端調(diào)用,所有請(qǐng)求地址以及請(qǐng)求參數(shù)都是暴露給用戶的。 我們每次請(qǐng)求一個(gè)HTTP請(qǐng)求,用戶都可以通過F12,或者抓包工具fd看到請(qǐng)求的URL鏈接,然后copy出來。這樣是非常不安全的,有人可能會(huì)惡意的刷我們的接口,那這時(shí)該怎么辦呢?防重放攻擊就出來了。 什
我們的API接口是為第三方服務(wù)/客戶端調(diào)用而設(shè)計(jì)的。所有請(qǐng)求地址和參數(shù)都是對(duì)用戶公開的。然而,每次發(fā)起HTTP請(qǐng)求時(shí),用戶都可以通過F12或抓包工具fd查看請(qǐng)求的URL鏈接,甚至將其復(fù)制出來。這種情況非常不安全,因?yàn)橛腥丝赡軙?huì)惡意刷我們的接口。這時(shí),防重放攻擊就顯得尤為重要。
防重放攻擊是指通過惡意重復(fù)發(fā)送已經(jīng)獲取的有效數(shù)據(jù)包來攻擊系統(tǒng)。以掘金文章點(diǎn)贊為例,當(dāng)用戶點(diǎn)贊后,H5會(huì)向掘金后端服務(wù)器發(fā)送請(qǐng)求。用戶可以通過F12查看完整的請(qǐng)求參數(shù),包括URL和參數(shù)等,然后將其復(fù)制出來,實(shí)施重放攻擊。
具體來說,服務(wù)端返回的是重復(fù)點(diǎn)贊,也就是掘金并沒有采取防重放攻擊的措施。掘金通過查詢數(shù)據(jù)庫(推測(cè)item_id是唯一索引值)來判斷是否已經(jīng)點(diǎn)贊,然后返回前端邏輯。
那么,我們理解的放重放攻擊是指什么呢?
簡(jiǎn)單來說,就是前端和客戶端約定一個(gè)算法(比如md5),通過加密時(shí)間戳+傳入字段來防止重復(fù)請(qǐng)求。然后,這個(gè)時(shí)間戳可以設(shè)定為30秒或60秒過期。如果30秒內(nèi)有人不斷刷我們的接口,我們還可以新增一個(gè)字段為nonceKey,30秒內(nèi)隨機(jī)不重復(fù)。這個(gè)字段存放在Redis,并且30秒過期。如果下一次請(qǐng)求nonceKey還在Redis中,我們就認(rèn)為是重復(fù)請(qǐng)求,可以拒絕。
通過這樣簡(jiǎn)單的算法,就可以實(shí)現(xiàn)防重放攻擊。
防重放攻擊的算法實(shí)現(xiàn)如下:
首先定義一個(gè)全局?jǐn)r截器:
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate redisService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 省略部分代碼
}
}
定義具體的算法實(shí)現(xiàn):
public class SecretUtils {
// 省略部分代碼
}
前端會(huì)通過預(yù)先約定好的算法和方式,將字符串從小到大進(jìn)行排序 + timestamp,然后md5進(jìn)行加密生成token傳給后端。后端根據(jù)算法+方式來校驗(yàn)token是否有效。如果其中有人修改了參數(shù),那么token就會(huì)校驗(yàn)失敗,直接拒絕即可。如果沒修改參數(shù),timestamp如果大于60秒,則認(rèn)為是防重放攻擊,直接拒絕;如果小于30秒,則將nonceKey加入到Redis里面。這里nonceKey用的是timestamp字段,如果不存在則第一次請(qǐng)求,如果存在,則直接拒絕即可。
防重放攻擊的Q&A:
Q:客戶端和服務(wù)端生成的時(shí)間戳不一致怎么辦
A:客戶端和服務(wù)端生成的是時(shí)間戳,不是具體的時(shí)間。時(shí)間戳是指格林威治時(shí)間1970年01月01日00時(shí)00分00秒(北京時(shí)間1970年01月01日08時(shí)00分00秒)起至現(xiàn)在的總秒數(shù)。
Q:HTTPS數(shù)據(jù)加密是否可以防止重放攻擊
A:不可以。HTTPS是在傳輸過程中保證了加密,也就是說如果中間人獲取到了請(qǐng)求,他是無法解開傳輸?shù)膬?nèi)容的。
舉個(gè)最簡(jiǎn)單的例子,上課和同學(xué)傳紙條的時(shí)候,為了不讓中間給遞紙條的人看到或者修改,可以在紙條上寫成只有雙方能看明白密文,這樣遞紙條的過程就安全了,傳紙條過程中的人就看不懂你的內(nèi)容了。但是如果給你寫紙條的人要搞事情,那就是加密解決不了的了。這時(shí)候就需要防重放來解決了。
Q:防重放攻擊是否有用,屬于脫褲子放屁
A:個(gè)人感覺有一點(diǎn)點(diǎn)吧。比如防重放攻擊的算法+加密方式其實(shí)大多數(shù)用的都是這些,其實(shí)攻擊人很容易就能猜到token生成的方式,比如timestamp + 從小到大排序。因此我們加入了salt來混淆視聽,這個(gè)salt需要前端、客戶端安全的存儲(chǔ),不能讓用戶知道,比如js混淆等等。但其實(shí)通過抓包,js分析還是很容易能拿到的。但無形中增加了攻擊人的成本,比如網(wǎng)易云登錄的js加密類似。
Q:做了防重放,支付,點(diǎn)贊等是否不需要做冪等了
A:需要。最重要的冪等,一定要用數(shù)據(jù)庫來實(shí)現(xiàn),比如唯一索引。其他都不可相信。
以我個(gè)人的理解,防重放用處不大。其他安全措施,比如非對(duì)稱的RSA驗(yàn)簽更加有效。就算用戶拿到了請(qǐng)求的所有信息,你的接口也一定要做冪等的,尤其是像支付轉(zhuǎn)賬等高危操作,冪等才是最有用的防線。而且防重發(fā)生成token的算法,大家都這樣搞,攻擊者怎么可能不知道呢?這點(diǎn)我不太理解。
現(xiàn)在面試也比較考驗(yàn)面試官的水平,下篇我會(huì)講下最近的一些面試體驗(yàn)和感受,歡迎大家點(diǎn)贊收藏。
小編推薦閱讀機(jī)器學(xué)習(xí):神經(jīng)網(wǎng)絡(luò)構(gòu)建(下)
閱讀華為Mate品牌盛典:HarmonyOS NEXT加持下游戲性能得到充分釋放
閱讀實(shí)現(xiàn)對(duì)象集合與DataTable的相互轉(zhuǎn)換
閱讀鴻蒙NEXT元服務(wù):論如何免費(fèi)快速上架作品
閱讀算法與數(shù)據(jù)結(jié)構(gòu) 1 - 模擬
閱讀5. Spring Cloud OpenFeign 聲明式 WebService 客戶端的超詳細(xì)使用
閱讀Java代理模式:靜態(tài)代理和動(dòng)態(tài)代理的對(duì)比分析
閱讀Win11筆記本“自動(dòng)管理應(yīng)用的顏色”顯示規(guī)則
閱讀本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請(qǐng)發(fā)郵件[email protected]
湘ICP備2022002427號(hào)-10 湘公網(wǎng)安備:43070202000427號(hào)© 2013~2025 haote.com 好特網(wǎng)