事件簡述

這是一件發生在前段時間的事情,當時的情況是這樣的:一個新的功能模塊上線之后,出現短信接口被惡意訪問調用的情況,請求數量很大,而且通過查看短信服務商控制臺也發現,短信發送量在飆升,看著統計曲線的增長,緊張的氣氛也漸漸變得更濃,很明顯,事情并不是遇到一個bug那么簡單,因為牽涉到服務費用,需要立即解決。

當然,接口被惡意訪問的這個問題已經解決,因此寫了這篇文章,可以做一下簡單的記錄,并且靜下心來分析一下其中的問題了,看完這個案例,大家也可以一起討論討論。

問題分析

日志增長

這是當時的短信接口日志數量曲線,某一個時間點突然增長了起來并且沒有降下去的意思,通過日志分析發現,攻擊者用的不同IP、不同號碼進行惡意調用,請求量較大,趕緊將事件做了記錄并通知了相關人員,和同事做了溝通后,大家也都提出了自己的意見:有人說趕緊修改前端功能,發一版新的APP,有人說修改后端代碼,緊急補救一下,也有人說要不要先關停一下服務......在網上技術論壇搜了一下相關問題,好像碰到這種事情的也不少,基本思路都是加驗證碼,做好安全驗證,被攻擊了無可奈何之類的云云。

簡單對各個方案做了整理:

  • 修改url(APP已經上線,暫時無法修改)。
  • 添加驗證碼驗證(APP已經上線,暫時無法通過這種方式來解決)。
  • 停掉短信服務(不現實,其他功能模塊也需要調用短信服務,不考慮實施)。
  • 短信服務商自帶防攻擊,等一段時間,讓攻擊者自己停止攻擊(雖然短信服務商自帶防攻擊,但是依然會出現大量的垃圾請求,而且服務商只是針對次數和時間做了限制,一段時間后依然會發送短信,因此,危害和損失還是不小的,問題依然急需處理掉,裝鴕鳥是解決不了問題的)

解決方案

在用戶交互界面攔截請求已經不現實了,因為移動端短時間內是無法立刻升級的,而等待攻擊停止的方案也不可取,選擇逃避和等待是解決不了問題的,因此最終的決定就是修改后端接口邏輯和代碼。找到最關鍵的問題,雖然存在網絡攻擊,但是真正需要立刻解決的是短信服務接口的調用問題,當務之急是修改短信發送接口,盡快止損。

通過討論和簡單的分析,最終是決定先修改后端邏輯緊急打一個線上補丁,移動端也做同步修改,等待發版。

黑名單模式攔截

由于接口一直被調用,需要緊急處理,減少短信服務費用的損失,因此一開始的出發點放在了手機號碼上,針對手機號碼做驗證,采用黑名單的模式,對于此接口中出現的號碼,在一定次數的請求后就立刻加入到黑名單列表中,再次請求時,如果是黑名單中的號碼,直接返回錯誤碼,不做任何其他處理,也不會調用短信發送接口,這種方式可能會誤傷到真實用戶,但是情況比較特殊,因此就選擇了這個應急方案,緊急修改了后端代碼,對部分代碼邏輯做了修改,添加手機號碼的黑名單功能。在短信發送模塊中,對號碼進行驗證,如果一段時間內多次請求同一個號碼的話,將號碼存入數據庫視為黑名單中的號碼,不會發送短信。 黑名單模式

攔截了近700個手機號碼,這些號碼中應該很多是空號吧: 短信黑名單

請求驗證攔截

上面的方法雖然起到了一定的作用,但是依然無法很好的解決掉問題,為什么這么說呢?因為即使利用了黑名單模式,在進入到黑名單列表之前,依然會發送短信,試想一下每分鐘1000次的惡意請求,即使拉黑了其中的一部分號碼,還是會有一部分漏網之魚會被當做正常數據,然后請求短信服務商接口發送短信,這也是一個不小的體量,黑名單模式可以處理一些問題,但是只能起到微小的作用,還需要進一步修改后端邏輯。

回到大家都提到的用驗證碼做安全驗證,前端雖然無法立即更新添加驗證碼界面和處理邏輯,但是驗證碼的設計就是識別正常請求和非法請求,因此找到一個方法能夠識別請求是否非法即可,并不一定非要添加驗證碼功能。本模塊在設計接口之初,就做了數據傳輸規定,移動端向后端發送請求時,必須在請求頭中放入一些參數,這些參數本來是做分析用的,但是在這里起到了很大的作用,因此可以在請求對象request上做文章,攻擊請求只是發送請求到url,攻擊者也只知道url并不知道請求參數設計,因此針對這點做驗證,應該可以攔截掉所有的惡意請求了,甚至請求都不會到達黑名單驗證環節就已經被處理掉了。

再次修改后端代碼,由請求信息request對象入手,從請求對象request中提取數據做校檢,甄別是否為正常請求,如果是正常請求,數據中的參數不會為空且參數值是可控的,而惡意虛假請求中則不含有這些參數,因此直接返回錯誤碼不作處理即可,這個補丁打上之后,短信服務費用的損失就不會再增加了。 驗證參數 非法請求不做處理,甚至都已經不需要黑名單攔截了。

短信發送量圖片 當時的短信發送量統計,在做了驗證之后,直接降了下去。

結語

不管是前端驗證碼,或者這次采取的驗證請求方式,都是一種驗證方式,用來甄別是否為移動端APP發送過來的正常請求,如果不是,就不做處理,通過日志和黑名單數據可以得出結論,短信發送的問題已經解決。

這個事件也說明,**安全驗證不能掉以輕心,也不能心存僥幸心理,**一旦被心存惡意之人找到漏洞,還是挺難過的。前端驗證沒有完全考慮到,后端驗證攔截也做的不到位,因此出現了這種情況,需要檢討和反思,而且處理方式也不是特別得當,一開始的黑名單模式并沒有完全杜絕掉短信發送的問題,又去做了后面的補救,當時確實比較緊張,因此想到能用的方法就趕緊用在了修改上面。

為何說驚險和緊張,試想一下:周末剛剛在家里修整了兩天,周一的早晨,打完卡坐在工位上悠閑的喝著茶,悠悠的打開瀏覽器查看系統日志,忽然發現這個訪問量有點大呀,隱隱覺著不對,認真的查了一下發現,接口被攻擊了,而且是短信發送的接口,看著一條條的短信因為攻擊而發送出去,那一條條的短信,是白花花的銀子啊,能不緊張嗎!什么感覺?吃著火鍋唱著歌,突然就被麻匪給劫了,跟葛大爺一樣,就是那種感覺。

至于說險勝,是因為雖然暫時解決了短信發送的問題,不會再進一步的造成金錢的損失,卻存在另外一個問題:大量的惡意請求。