一個(gè)正經(jīng)開(kāi)發(fā)人員的安全意識(shí)
在任何的開(kāi)發(fā)過(guò)程中,只要涉及到安全的問(wèn)題,我們都需要牢記Shannon的這句話(huà),雖然是與密碼學(xué)相關(guān),但是也可以應(yīng)用到服務(wù)的安全,也就是說(shuō),我們應(yīng)該假定攻擊者最終將完全熟悉這個(gè)系統(tǒng)。
作為交付業(yè)務(wù)的開(kāi)發(fā)人員來(lái)說(shuō),安全從來(lái)都是一個(gè)重要的話(huà)題,并且如果是從事健康、金融等相關(guān)領(lǐng)域,在北美的合規(guī)性上更是尤甚。除了從業(yè)務(wù)上對(duì)安全做的一些考慮,比如密碼強(qiáng)度,Multi-Factor Authentication(MFA),更多的安全相關(guān)性可能對(duì)于一個(gè)正經(jīng)開(kāi)發(fā)人員來(lái)說(shuō),可能很難面面俱到的考慮周全。在此,想借用一個(gè)和健康醫(yī)療相關(guān)的項(xiàng)目來(lái)對(duì)項(xiàng)目上所面臨的安全需求以及實(shí)踐進(jìn)行介紹。
背景
除了在業(yè)務(wù)上我們滿(mǎn)足用戶(hù)的安全需求,以及一些對(duì)常規(guī)的離散的安全了解(TLS,injection,DoS等),我們沒(méi)有一個(gè)全局的系統(tǒng)的安全方面的考慮,再加上客戶(hù)也提出了一條條沒(méi)有組織沒(méi)有結(jié)構(gòu)的安全需求,在與客戶(hù)對(duì)話(huà)之前需要做大量的討論和研究。
對(duì)于計(jì)算機(jī)安全的定義來(lái)說(shuō),機(jī)密性、隱私性和完整性是三個(gè)關(guān)鍵目標(biāo),如果從計(jì)算機(jī)安全模型來(lái)說(shuō),又包括硬件、軟件和通信等。對(duì)于這樣的分類(lèi)和定義,如果我們能很好的做出威脅建模,那么結(jié)果可能是比較全面,但是問(wèn)題又來(lái)了,在組內(nèi)大多數(shù)成員沒(méi)有威脅建模的經(jīng)驗(yàn)下,我們又很難做好一個(gè)威脅建模,這樣我們的結(jié)論也可能達(dá)不到我們想要的目標(biāo)。
那么這樣的話(huà),從一個(gè)比較直觀(guān)并且概括的層面,能讓大家了解我們可能面對(duì)的保護(hù)和攻擊,可以在最基本的面上有個(gè)大概了解。
應(yīng)用 Application
認(rèn)證授權(quán)
- 所有需要認(rèn)證的請(qǐng)求會(huì)通過(guò)Gateway Ambassador,通過(guò) Ambassador 提供的 Filter 和 FilterPolicy 來(lái)控制到認(rèn)證的接口上
- 不同接口會(huì)有不同的權(quán)限,這一層是在應(yīng)用層上實(shí)現(xiàn)
- 所有的用戶(hù)只能訪(fǎng)問(wèn)屬于自己的 tenant 內(nèi)的資源,這也是在應(yīng)用層上實(shí)現(xiàn)
漏洞
對(duì)于這類(lèi)攻擊其實(shí)我們經(jīng)常能聽(tīng)到很多,比如 SQL injection, XSS 等等。這些攻擊在我們目前使用的通用框架中其實(shí)已經(jīng)幫助我們做了很好的保護(hù),比如現(xiàn)在的 ORM 框架早已有 Parameterized queries 來(lái)防止 injection(前提是我們不要去拼接 query),Spring Security 也提供了 CSP header 來(lái)保護(hù) XSS。
再比如CSRF,在目前我了解到的使用 Spring 的應(yīng)用中,都是disable的狀態(tài)。因?yàn)槠鋵?shí)如果我們是使用的JWT token來(lái)做認(rèn)證,而不是基于 cookie 來(lái)做認(rèn)證,那么我們也不用做更多來(lái)防止 CSRF。
日志
在我們的實(shí)施方案中,我們對(duì)日志進(jìn)行了不同的分類(lèi)。一類(lèi)是基本的服務(wù)應(yīng)用日志,主要便于生產(chǎn)環(huán)境的問(wèn)題識(shí)別;另一類(lèi)是審計(jì)日志,主要是記錄用戶(hù)的行為,包括哪個(gè)用戶(hù)從某個(gè) IP 做了什么樣的請(qǐng)求操作,也可以防止用戶(hù)抵賴(lài)(Repudiation of Action)。
GCP 中的日志服務(wù)提供了 Log buckets,我們對(duì)以上兩類(lèi)日志分別放到了不同的 bucket 里面,這樣也可以對(duì)于不同的日志設(shè)置不同的 retention period。
郵件
郵件的安全可能是我們?nèi)菀缀雎缘囊粋€(gè)問(wèn)題,在郵件上設(shè)計(jì)到的安全有DMARC, SPF 和 DKIM。因?yàn)轫?xiàng)目上使用的是郵件服務(wù)Sendgrid,所以對(duì)于 DMARC, SPF 和 DKIM 是在郵件服務(wù)中實(shí)施的。在這里是想讓大家可以了解到即便是郵件功能,也不能忽略其安全的地位。
基礎(chǔ)設(shè)施 Infrastructure
網(wǎng)絡(luò)
如果實(shí)在信賴(lài)的 VPC 之內(nèi),我們可以將 TLS 在 Load Balancer 就終止,任何在這個(gè) VPC 內(nèi)的流量都是以解密之后傳輸?shù)摹5鋵?shí)在 cluster 內(nèi)服務(wù)和服務(wù)之間的安全也是需要保證的。
Firewall 的正確配置,開(kāi)啟 DNSSEC,配置 Egress 到信任的外部服務(wù),利用 WAF 來(lái)控制服務(wù)的訪(fǎng)問(wèn)等等,這些都是在網(wǎng)絡(luò)上我們可以考慮的安全要素,因?yàn)榫W(wǎng)絡(luò)安全是一個(gè)比較大的另一個(gè)話(huà)題,并且我知識(shí)也有限,就不展開(kāi)講更多。
Security Posture Monitoring
我們需要知道我們服務(wù)的資產(chǎn),并且哪些資產(chǎn)在業(yè)務(wù)上有重要意義,我們還需要知道我們做了哪些安全措施來(lái)保護(hù)我們的資產(chǎn)。
部署在 GCP 之上的資產(chǎn),GCP 的 Security Command Center 可以幫助我們了解和修補(bǔ) GCP 的安全和風(fēng)險(xiǎn)。其提供了不同等級(jí)的服務(wù),詳細(xì)的可以參考 Security Command Center。
密碼秘鑰輪訓(xùn)
定期或者主動(dòng)去輪換現(xiàn)有的密碼。
GCP 的 Secret Manager 配合 pubsub 和 CloudFunction 可以設(shè)置 rotation period 來(lái)幫助我們定期更改密碼,但是我們的密碼有些是集成了第三方系統(tǒng)的 api key 或者是 private key,這樣不太方便使用 Secret Manager 提供的 rotation 功能。對(duì)于這樣的第三方密碼,還是需要運(yùn)維人員手動(dòng)在第三方服務(wù)中更新密碼,或者使用其提供的 API 或者 Script 來(lái)重新生成密碼,然后用 Terraform 控制 GCP Secret Manager 來(lái)幫助我們管理密碼。
但這里有個(gè)問(wèn)題是密碼是不能明文存儲(chǔ)在對(duì)應(yīng)的 Terraform repo 中,所以目前我們?cè)陧?xiàng)目中只是將密碼文件加密后再上傳,對(duì)于 Terraform 來(lái)更新密碼還是在本地執(zhí)行 terraform apply,還沒(méi)有一個(gè)比較有效的方式。
安全檢查 / 測(cè)試 Security Check / Testing
靜態(tài)掃描
我們可以使用很多靜態(tài)掃描工具幫助我們提高代碼質(zhì)量,也可以幫助我們?cè)诖a層面上泄露安全風(fēng)險(xiǎn)。
這些工具會(huì)集成到我們的 CI 之上,比如 gitleaks 來(lái)幫助我們檢查是否有硬編碼的密碼、私鑰等信息,OWASP Dependency Check 來(lái)檢查 vulnerability。
動(dòng)態(tài)掃描
除了靜態(tài)掃描外,動(dòng)態(tài)掃描可以幫助我們檢查出應(yīng)用服務(wù)上的安全風(fēng)險(xiǎn),比如之前提到的 XSS,injection 等等,都可以利用周期性的動(dòng)態(tài)掃描來(lái)規(guī)避風(fēng)險(xiǎn)。
雖然不能完全依賴(lài)這類(lèi)的掃描工具來(lái)保護(hù)我們的應(yīng)用服務(wù),但是這在一定程度上可以緩解風(fēng)險(xiǎn)的可能性。
Mobile
Run Application Self Protection RASP
對(duì)于大多數(shù)應(yīng)用的外圍保護(hù)來(lái)說(shuō),比如防火墻,IDS,這些保護(hù)都只是對(duì)運(yùn)行環(huán)境的保護(hù),但是設(shè)計(jì)到應(yīng)用本身,這樣的保護(hù)不會(huì)具有針對(duì)性,也就是說(shuō)突破了這些保護(hù)的限制,一樣能對(duì)應(yīng)用造成威脅。
那么移動(dòng)端App,不像服務(wù)端的應(yīng)用部署在一個(gè)幾乎完全受我們控制的環(huán)境中,它可能運(yùn)行在一個(gè)已經(jīng)過(guò)時(shí)很久,或者不太安全的版本的 OS 上。這時(shí)候需要一個(gè)能提供自我保護(hù)的應(yīng)用。
在綠碼項(xiàng)目中,我們使用的是客戶(hù)合作的Promon SHIELD,其提供了比如 root detection, code obfuscation, code injection protection 和 screen reader protection 等等可配置的保護(hù)。
RASP 更多的是對(duì)應(yīng)用本身提供保護(hù),所以是其實(shí)現(xiàn)方式我理解無(wú)非是在應(yīng)用內(nèi),比如針對(duì)應(yīng)用特定場(chǎng)景的保護(hù),或者是在應(yīng)用外有一層保護(hù)膜,比如使用 Promon SHIELD 就是一層 wrapper,如下:
App Attestation
就如最開(kāi)始提到的,我們?cè)谠O(shè)計(jì)系統(tǒng)時(shí)就要考慮到攻擊者最終會(huì)完全熟悉我們的系統(tǒng)。那么設(shè)想攻擊者有了這些知識(shí)后,能不能做出一個(gè)和我們完全一模一樣的App。
如果在這個(gè)時(shí)候我們?cè)鯓尤シ乐惯@種類(lèi)似釣魚(yú)的攻擊發(fā)生。對(duì)于 iOS 和 Android 都有方式去做 attestation。
在我們項(xiàng)目上,對(duì)于A(yíng)ndroid 采用的是 SafetyNet Attestation,而iOS是利用通知推送的機(jī)制的形式。雖然本身 Android 也有通知推送機(jī)制,但是其推送地址和這個(gè)合法的 App 之間的關(guān)系僅僅是 package name,然而iOS的推送機(jī)制是基于 push certificate,所以對(duì)于 Android 使用的是其提供的 SafetyNet 更為可靠。
以下是簡(jiǎn)單的流程圖,感興趣的同事可以進(jìn)一步深究。
結(jié)語(yǔ)
在這里只是簡(jiǎn)單的從一個(gè)普通正經(jīng)開(kāi)發(fā)者的安全角度出發(fā),列舉了一些其他項(xiàng)目可能可以參考的安全實(shí)踐。但是安全遠(yuǎn)遠(yuǎn)不止于此,并且涉及到的知識(shí)也是非常之廣,以上提到的任何一點(diǎn)都可以有更深的討論。
【本文是51CTO專(zhuān)欄作者“ThoughtWorks”的原創(chuàng)稿件,微信公眾號(hào):思特沃克,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】

























