小知識分享:控制層儘量別暴露這樣的介面,避免橫向越權。

2023-09-09 21:00:38

前言

談不上是多麼厲害的知識,但可能確實有人不清楚或沒見過。

我還是分享一下,就當一個小知識點。

如果知道的,就隨便逛逛,不知道的,Get到了記得順手點個贊哈。

正文

1、介面別隨便暴露

當一個專案的維護週期拉長的時候,不斷有新增的需求,如果經手的人也越來越多,介面是會肉眼可見增多的。

此時,如果一個團隊沒有良好的規範和程式碼審查機制,就會導致許多不安全的介面被暴露出來。

比如下面這種介面:

/**
* 根據ID查詢患者資訊
*/
@GetMapping("/{id}")
public AjaxResult getById(@PathVariable("id") Long id) {
    PersonInfo personInfo = personInfoService.selectPersonInfoById(id);
    return AjaxResult.success(personInfo);
}

這種介面是我們部門以前審查出來的其中一個,類似這樣的介面還有很多。

這些介面都是不同的同事在緊湊的工作任務中寫的,慢慢就積累出了一堆。

還有些是為了方便,直接通過程式碼生成器生成的,而程式碼生成器是把常用的CRUD介面都給你生成出來,如果研發人員沒有責任心,可能就直接不管了,想著以後哪一天也許會用上呢。

別以為這種想法的人少啊,你整個職業生涯很可能就會遇見。

這就導致了,一堆用不上又不安全的介面出現了。

服務過政務機構、企事業單位、醫療等行業的工程師應該就知道,這些單位對於安全性的要求其實挺高的,尤其是這些年,會找專門的資訊保安公司做攻防演練。

最近兩年,很多省市甚至會自發組織全市的資訊保安攻防演練,在當前大環境下這也是符合國情的。

而攻防演練的目的之一就是找系統安全漏洞,這裡面就會有一個我本章要講的典型漏洞,介面的橫向越權。

2、什麼是橫向越權

廣義的解釋就是,該越權行為允許使用者獲取他們正常情況下無權存取的資訊或執行操作。

如果純粹從理論上理解,是很抽象的,所以我才把這個案例撈出來,讓你一次就懂。

我們再回過頭看看上面我貼出來的那段很正常的程式碼,就是根據id獲取使用者資訊,你一定曾經在一些專案中見過這種介面,提供給前端直接呼叫,比如使用者詳情、訂單詳情,只要是和詳情有關的,很可能前端會需要這麼一個介面。

那麼,問題在這裡,我們的id是不是有規則的呢?比如下面這樣:

可以看出來,id是自增的,增量是2。其實很多中小企業現在用MySQL都喜歡這樣設定自增id,有些會設定增量,有些乾脆就預設。

試想一下,我如果知道了id=865的使用者資訊,我也知道大部分中小企業喜歡用自增id,是不是就等於知道了1-1000000的使用者資訊,而使用者資訊可能包含身份證、手機號、詳細住址等非常敏感的內容。

這就是典型的橫向越權之一,我明明只應該拿到id=865這個使用者的資訊,但是通過非正常的方式,我暴力獲取了其他100萬個使用者資訊。

一旦真的發生這樣的事故,不管最終結果如何,這家公司基本上就進黑名單了,從此在行業中消失。

3、許可權控制不了嗎

一定會有人產生疑惑,SpringBoot介面怎麼可能直接放出來,一定都是有許可權控制的,沒有許可權是根本不可能存取到的。

我打個比方,如果是後臺管理這種,他是有登入的,登入後會產生token,token中是可以包含角色許可權的,那麼這種是沒有問題的。

但如果沒有登入操作呢,比如小程式這種,你開啟就直接是首頁各種資訊,前端調介面很可能傳遞的只有閘道器層的token,又該如何呢。

尤其是小程式雨後春筍一般湧現的那幾年,我曾經開啟過很多小程式,都是沒什麼許可權校驗的,就是直接點來點去。

直到近幾年,這種現象才慢慢消失,很多小程式開啟後,會提示你授權登入,比如微信小程式,你一定遇到過開啟小程式後讓你授權登入的場景,如果不授權登入,你絕對做不了很多操作,這是很多網際網路企業的安全意識都加強的結果。

我所在的公司早年剛進入醫療行業就經歷過這種事情,為了佔坑拿下了很多專案,但缺乏安全意識和管理規範,程式設計師也是來來走走,你寫兩個我寫兩個,導致不少介面都存在安全隱患。

直到被攻防演練攻破,甲方下發整改通知,還要我們寫事故報告、原因、解決方案等等一大堆,我們才慌了。

連夜開會討論出一套基本的安全整改思路,然後開始加班加點做安全改造。

我印象最深的就是其中這個介面橫向越權,只傳遞了閘道器層的token,而沒有細化到個人的許可權控制,導致被資訊保安公司通過抓包等一些我不瞭解的技術把token拿到了,然後直接橫向獲取到了很多使用者敏感資訊。

當時這個事情鬧得很厲害,考慮到只是攻防演練,同時客戶方對公司還保留信任,才只要求我們限期整改,否則就直接替換了。

所以,記得以後寫介面的時候別隻考慮業務邏輯,安全性也是考量之一。

4、如何防範

防範的方式,我歸納了這麼幾點:

1、不用的介面儘量刪掉,這樣也避免了多餘介面埋下的安全隱患;

2、團隊要有安全規範,比如敏感欄位加密,引入程式碼審查機制,縮小安全隱患出現的範圍;

3、帶登入的終端,除了閘道器層校驗,要精確控制登入使用者的角色及許可權;

4、不帶登入的終端,除了閘道器層校驗,要根據使用者的唯一資訊,來做授權登入,授權不成功不允許做其他操作,這也是現在比較流行的方式。

我個人理解,第4點和第3點本質一樣,因為不帶登入,所以要想辦法制造登入,而目前比較友好的方式還是一鍵授權登入,不管是根據openid、手機號等等,總之要找到一個規則,這樣省去了使用者手動操作登入的時間。

總之,一定要控制使用者只能看到屬於自己的內容,避免橫向越權。

總結

如果寫的不好,還望大家原諒,只是分享了曾經工作中發生過的和安全改造有關的事情。

現在的程式設計師其實瞭解和接收的知識技術是挺多的,許多人其實都知道這些。

希望不知道的人,能夠因為我的文章得到一點點幫助。

最後,大家其實可以去試一試,開啟微信小程式,搜尋下你們所在城市的某某中心醫院,看看這樣的醫療小程式開啟後是什麼樣的,是不是有授權登入,或者其他方式來控制許可權,搞不好一部分人能遇到有意思的事情。


如果喜歡,請點贊關注哦↓↓↓,持續分享乾貨!