【編者按】千里之堤毀于蟻穴。服務(wù)安全有點類似于機(jī)場安檢。工作人員會檢查每一個人,禁止他們帶某些東西上飛機(jī)等等,盡管99.9999%的人都不會劫持飛機(jī)。而機(jī)場采取的所有措施針對的都是0.0001%的情況。因為后果影響非常大。
作者 | Madalin Ilie
譯者 | 彎月
出品 | CSDN(ID:CSDNnews)
軟件的安全問題既困難又復(fù)雜。許多人認(rèn)為安全屬于正常開發(fā)流程之外的東西。通常被視為某些安全人員的責(zé)任,他們只需要關(guān)注安全,不需要理解我們在復(fù)雜的微服務(wù)、事件驅(qū)動、API優(yōu)先戰(zhàn)略以及云生態(tài)系統(tǒng)中快速交付的業(yè)務(wù)價值。我認(rèn)為正是由于這種思想,我們很難在早期階段思考安全問題,找出任何有可能破壞系統(tǒng)的人或事。安全導(dǎo)致復(fù)雜的壞境又多了一層復(fù)雜。安全不僅僅體現(xiàn)了現(xiàn)代架構(gòu)的技術(shù)復(fù)雜性,而且還有很多其他方面的問題,比如快速走向市場、嚴(yán)格的期限、團(tuán)隊內(nèi)部問題、性能問題、流程太多、會議太多等等。雖然安全非常復(fù)雜,但是它并不會在某一天里突然破壞你的系統(tǒng)??赡茉诮?jīng)過數(shù)月/數(shù)年后,才會有人發(fā)現(xiàn)漏洞。那么,為什么我們要從第一天起就關(guān)注安全呢?話雖沒錯,第一天就出現(xiàn)安全問題的可能性非常小。我們都希望集中精力完成具有直接價值的功能,而不是預(yù)防未來可能出現(xiàn)的問題。然而,關(guān)鍵在于,安全問題可能會導(dǎo)致整個系統(tǒng)癱瘓。這對于你和你的用戶都非常不利。
那么,如何在不過度設(shè)計安全性和偏執(zhí)于一切之間取得平衡,同時仍然還能專注于業(yè)務(wù)價值呢?這其實是一種思維模式,而不是一個單獨的關(guān)注點。我并不是說每個人都需要成為安全專家以及無所不知。我是說人們應(yīng)該開發(fā)安全軟件,就像他們開發(fā)軟件一樣。通過一種方式將引入漏洞的可能性降到最低。
灌輸這種思維模式的最佳方式是采用一套標(biāo)準(zhǔn)和實踐來培養(yǎng)習(xí)慣。繼續(xù)拿機(jī)場安檢做類比,你不能讓安檢人員自行做決定:
“這個人看上去是好人,他的手提行李可以攜帶剪刀和刀。”
“這位先生看上去嚴(yán)重脫水,他可以攜帶一大瓶液體上飛機(jī)!”
你需要創(chuàng)建一套平等且適用于每個人的規(guī)則和程序(即標(biāo)準(zhǔn))。此外,你還需要制定一套關(guān)于如何處理特定情況的指導(dǎo)方針(即實踐):如果你發(fā)現(xiàn)手提行李中有可疑物品,則可以單獨檢查。
接下來,我將詳細(xì)介紹涵蓋整個系統(tǒng)發(fā)展生命周期的標(biāo)準(zhǔn)和實踐。雖然這個列表無法做到詳盡(對于有些小節(jié)的內(nèi)容,你可能有更多良好的實踐),但我希望能夠幫助你思考一些不太常見的情況。
安全的重點
我簡單地將安全問題分為了兩個主要領(lǐng)域:
基礎(chǔ)設(shè)施安全:與應(yīng)用程序在生產(chǎn)中的部署和運行相關(guān)的安全問題。
應(yīng)用程序安全性:與應(yīng)用程序的實現(xiàn)以及業(yè)務(wù)背景細(xì)節(jié)相關(guān)的安全問題。
關(guān)于如何解決這兩個問題,有很多資源:
PCI 安全要求():側(cè)重于財務(wù)軟件,但也可作為其他系統(tǒng)的最佳實踐。
安全代碼():有關(guān)開發(fā)、測試、架構(gòu)以及開發(fā)運維的通用實踐。
有關(guān)安全編程的十大最佳實踐():側(cè)重于某些編程語言的安全編程最佳實踐,也有一些通用的實踐。
OWASP 備忘單系列():覆蓋了大多數(shù)軟件開發(fā)領(lǐng)域的備忘單。
上述資源非常全面,包括許多解決系統(tǒng)發(fā)展生命周期內(nèi)有關(guān)安全問題的細(xì)節(jié)和實踐。每位開發(fā)人員都應(yīng)該定期做檢查,并掌握最新信息。但在實踐中,我們很難做到。下面,我將設(shè)法總結(jié)出我們需要思考的一些重要問題(注意:這些實踐與業(yè)務(wù)領(lǐng)域無關(guān))。雖然這不是一份詳盡的清單,也不是靈丹妙藥,但它可以幫助你建立堅實的基礎(chǔ),將發(fā)生安全問題的可能性降到最低。
解決安全問題
基礎(chǔ)設(shè)施的安全比較容易解決,因為很多人都會使用產(chǎn)品或云服務(wù)。這些產(chǎn)品和服務(wù)已經(jīng)包含了非常好的安全功能,如果你使用Web應(yīng)用程序防火墻,則可以相信該產(chǎn)品能夠保障安全,不需要由你來實現(xiàn)安全。我并不是說這樣做會更容易,而是說你有更多控制。
應(yīng)用程序的安全則更加難以預(yù)測。你需要依靠開發(fā)人員的技術(shù)來實現(xiàn)安全。你需要確保他們不會做愚蠢的事情,比如在源文件中存儲明文密碼。
以下是我認(rèn)為能夠幫助你建立安全思維方式的實踐列表,主要面向常規(guī)開發(fā)人員。這里的“常規(guī)”指的是實際實現(xiàn)代碼的人,而不是其他專注于設(shè)計、規(guī)劃或管理的人。這些規(guī)則關(guān)注的都是構(gòu)建 (REST) API 時的應(yīng)用程序安全。雖然表面看起來它們與安全并沒有直接的聯(lián)系,但最終它們都可以減少引入安全問題的可能性。
注意:本文的大多數(shù)示例都使用了Java。
標(biāo)準(zhǔn)
如上所述,標(biāo)準(zhǔn)的使用是建立思維方式的主要機(jī)制。所有項目都應(yīng)該采用同一套標(biāo)準(zhǔn)。并非所有人都喜歡標(biāo)準(zhǔn),有些人可能會認(rèn)為標(biāo)準(zhǔn)限制了人們的選擇和創(chuàng)造力。但我認(rèn)為,這是一種簡單的獲得統(tǒng)一性的方法,尤其是當(dāng)多個團(tuán)隊在同一平臺上工作時。建立標(biāo)準(zhǔn)之后,新成員可以更輕松地加入項目,而且還能降低引入bug、不一致或在某些愚蠢的事情(比如空格還是制表符)上發(fā)生爭執(zhí)的可能性。我們可以將這些時間節(jié)省出來討論更有意義的問題。標(biāo)準(zhǔn)不一定要涉及很多細(xì)節(jié),大多數(shù)標(biāo)準(zhǔn)應(yīng)該說明建立在現(xiàn)有實踐之上的原則和選擇。
文檔
需要考慮的關(guān)鍵事項:
將代碼的接口以及API合同寫在文檔中;
定義文檔策略:
整體的文檔策略是什么?
項目的 README.md 文件中包含什么?
是否需要更新更廣泛的文檔?
采用哪些畫圖工具?
是否使用輕量級架構(gòu)決策記錄?
文檔應(yīng)當(dāng)存儲在Git代碼庫中?還是采用單獨的工具?
如果存儲在項目中,推薦的文件夾結(jié)構(gòu)是什么?
通用(微)服務(wù)設(shè)計指南
需要考慮的關(guān)鍵事項:
使用藍(lán)圖/模板/原型作為所有(微)服務(wù)的起點;
將藍(lán)圖與所有公共庫、插件等捆綁在一起,并且必須符合標(biāo)準(zhǔn);
每個(微)服務(wù)必須能夠通過運行一個命令來啟動;
(微)服務(wù)只能通過API/事件處理數(shù)據(jù),沒有后門;
每個(微)服務(wù)都是獨立的;
所有(微)服務(wù)都符合應(yīng)用的十二要素,以及其他標(biāo)準(zhǔn)。
代碼格式/風(fēng)格
選擇一種代碼風(fēng)格,并貫徹到底。如果可以,在提交前自動格式化。
命名約定
選擇一種約定,并貫徹到底。
API標(biāo)準(zhǔn)
需要考慮的關(guān)鍵事項:
遵循 REST 命名實踐(名詞、復(fù)數(shù)以及其他常見的標(biāo)準(zhǔn)),網(wǎng)上有很多指南,選擇一種,并貫徹到底;
與命名規(guī)則統(tǒng)一。該標(biāo)準(zhǔn)適用于一切,比如負(fù)載對象命名、屬性等,而不僅限于端點。無論是駝峰式、蛇式還是烤肉串式,選擇一種,并貫徹到底;
POST、PUT、PATCH的響應(yīng)包含有意義的主體;
使用有意義的 HTTP 狀態(tài)碼,不要遇到錯誤就返回 400;
所有端點必須返回有意義的錯誤情況;
提供錯誤列表(更多細(xì)節(jié)請參見錯誤處理部分的介紹);
考慮 OpenAPI,以及契約優(yōu)先開發(fā),即剛開始的時候編寫 OpenAPI 契約,與(內(nèi)部)消費者溝通,這樣可以實現(xiàn)更好的并行開發(fā);
使用有意義的描述和示例記錄 OpenAPI 契約;
所有(內(nèi)部)API 必須使用 CorrelationId/TraceId 的標(biāo)頭;
默認(rèn)情況下,所有 API 輸入都必須有非常嚴(yán)格的限制;
所有 API(內(nèi)部或外部)都必須經(jīng)過身份驗證,最好采用實時授權(quán);
所有 API 必須重用相同的公共數(shù)據(jù)結(jié)構(gòu):可以采用通用的地址、人、國家等,也可以定義特定于業(yè)務(wù)的數(shù)據(jù)結(jié)構(gòu);
所有 API(內(nèi)部或外部)只能通過 HTTPS 公開;
考慮在 API 的響應(yīng)中返回安全標(biāo)頭,例如:Cache-Control: no-store,Content-Security-Policy: frame-ancestors 'none',Content-Type, Strict-Transport-Security,X-Content-Type-Options: nosniff,X-Frame-Options: DENY等。
內(nèi)部 API 之間的通信不應(yīng)該通過互聯(lián)網(wǎng)(除非是架構(gòu)有意為之,或有此類要求);
不要通過互聯(lián)網(wǎng)公開管理端點;如果有這種要求,請使用身份驗證;
確保所有 API 都會嚴(yán)格驗證收到的請求:不允許使用未記錄的 JSON 字段、拒絕格式錯誤的 JSON 等;
正確使用數(shù)據(jù)類型,不要將所有內(nèi)容都作為字符串;
盡可能使用枚舉值;
定義字符串的長度限制,定義數(shù)字的最小值/最大值;
定義每個字符串的輸入限制模式;
某些屬性有明確的定義,因此定義正則表達(dá)式很容易,比如國家代碼一律以“[A-Z]+”開頭。但有些屬性很難定義正則表達(dá)式,比如考慮到所有語言中人們的姓氏,這個屬性(lastName)的要求就會非常寬松。建議定義一些能夠防止出現(xiàn)奇怪字符的模式,比如 Unicode 控制字符、分隔符或符號;推薦的正則表達(dá)式對象如下:“^[^\p{C}\p{Z}\p{So}]*[^\p{C}\p{so}]+[^\p{C}\p{Z}\p{So}]*$”,但這并不能確保程序可以免受任何類型的注射,你仍然需要很好地理解數(shù)據(jù)的去向和處理方式,但至少可以確保表情符號不會破壞你的系統(tǒng)。
標(biāo)準(zhǔn)日志
需要考慮的關(guān)鍵事項:
日志的格式:使用逗號分隔的鍵值對(key=value)?還是使用JSON對象?選擇適合工具的格式;
日志的每一行都包含 CorrelationId/TraceId,這樣可以方便工具創(chuàng)建儀表板;
日志中記錄方便理解實際情況的信息:哪個實體?業(yè)務(wù)領(lǐng)域?成功了嗎?失敗了?
一些參考做法();
在實際的日志實現(xiàn)之上使用抽象層;例如在 Java中,使用由logback實現(xiàn)的slf4j;
將日志作為橫切關(guān)注點,利用面向切面的程序設(shè)計,僅在異常情況下記錄日志,限制敏感內(nèi)容的記錄;
不能將日志作為記錄一切備用信息的手段,將所有請求和響應(yīng)都完整地記錄下來。應(yīng)當(dāng)謹(jǐn)慎地記錄日志,即使在調(diào)試級別或較低級別中也應(yīng)如此。
更多有關(guān)日志記錄的參考信息()。
數(shù)據(jù)標(biāo)準(zhǔn)
需要考慮的關(guān)鍵事項:
使用現(xiàn)有的 ISO 標(biāo)準(zhǔn)處理廣為人知的對象:貨幣、日期、金額等;
定義可重復(fù)使用的特定于業(yè)務(wù)的對象;
API對象、數(shù)據(jù)庫實體和事件也需要采用這些標(biāo)準(zhǔn)。
處理數(shù)據(jù)
需要考慮的關(guān)鍵事項:
在處理數(shù)據(jù)之前清理數(shù)據(jù),下面是一個通用的清理正則表達(dá)式:“^[^\p{C}\p{Z}\p{So}]*[^\p{C}\p{so}]+[^\p{C}\p{Z}\p{So}]*$”,雖然無法杜絕所有的問題,但是可以刪除可能會導(dǎo)致系統(tǒng)崩潰的奇怪字符;
確保不會將輸入數(shù)據(jù)傳輸?shù)絻?nèi)部的訪問操作,如數(shù)據(jù)庫查詢、命令行執(zhí)行等。使用參數(shù)化的數(shù)據(jù)庫查詢,具體指定獲取的內(nèi)容與傳遞的內(nèi)容;
當(dāng)需要針對特定輸入的處理施加限制時,請使用白名單(而不是黑名單);
采用防御性編程實踐;
確保使用不易受到 XXE 或類似攻擊的高效 XML 解析器。最好不要使用 XML 作為輸入,除非上下文有這樣的強(qiáng)制要求。
日志數(shù)據(jù)
需要考慮的關(guān)鍵事項:
不要記錄敏感數(shù)據(jù)。如果出于某種原因仍然需要記錄,請屏蔽敏感數(shù)據(jù)。這里的敏感程度取決于具體的業(yè)務(wù)與法規(guī);
創(chuàng)建/使用一個庫,默認(rèn)屏蔽平臺中最敏感的數(shù)據(jù),例如,如果你正在處理付款,則默認(rèn)屏蔽銀行卡號,不要讓每個開發(fā)者自行決定;
考慮在每次添加新的敏感數(shù)據(jù)時擴(kuò)展該庫,如果需要添加大量數(shù)據(jù),則必須平衡性能;
日志記錄庫必須允許特定的配置,以便每個單獨的服務(wù)可以屏蔽額外的數(shù)據(jù),而無需擴(kuò)展該庫;
日志記錄庫必須提供清理方法(即通過調(diào)用特定的方法),確保所有情況都可以使用同一種清理技術(shù);
日志記錄庫必須在記錄數(shù)據(jù)之前清理數(shù)據(jù)(比如刪除所有與“\p{Z}\p{C}\p{So}”相匹配的字符);
日志記錄庫必須刪除 CR 和 LF 字符,以防止 CRLF 注入;
建立明確的日志歸檔策略。
存儲數(shù)據(jù)
需要考慮的關(guān)鍵事項:
只能存儲與當(dāng)前上下文或可預(yù)見的將來相關(guān)的數(shù)據(jù),數(shù)據(jù)存儲不能作為以備不時之需的手段;
數(shù)據(jù)的存儲必須遵守相關(guān)規(guī)定,你必須知道這一點;
某些數(shù)據(jù)不能明文存儲(比如信用卡號),可以使用硬件或軟件加密;
不能在純文本文件的版本控制中存儲隱私數(shù)據(jù)(密碼、加密密鑰、ssh 密鑰、私鑰等),必須使用專用產(chǎn)品或服務(wù),例如 Vault、HSM等;
在執(zhí)行敏感數(shù)據(jù)的加密或散列操作時,必須“加鹽”和/或“加胡椒”,以防止暴力攻擊;
考慮構(gòu)建(或使用)令牌化敏感數(shù)據(jù)的集中式服務(wù);
令牌化所有受某種監(jiān)管的數(shù)據(jù):銀行卡號、PII 數(shù)據(jù)等。所有(微)服務(wù)都應(yīng)該使用令牌(而不是實際的數(shù)據(jù)),并僅在需要時還原令牌,這可以最大限度地減少合規(guī)所需的工作,還可以更好地控制數(shù)據(jù);
加強(qiáng)令牌化解決方案的安全性,不允許從外部訪問其 API。
事件/消息標(biāo)準(zhǔn)
需要考慮的關(guān)鍵事項:
創(chuàng)建一個事件列表,讓每個人都知道每個事件的目的;
使用事件規(guī)范進(jìn)行驗證;
避免使用通用事件來發(fā)送一切消息,避免在不知情的情況下泄露敏感信息;
考慮用交換令牌代替包含敏感信息的實際數(shù)據(jù)。
配置管理
需要考慮的關(guān)鍵事項:
避免在源文件中硬編碼配置;
考慮使用集中式配置管理;
按環(huán)境分隔配置;
不要在源文件或版本控制中存儲隱私數(shù)據(jù)(密碼、api 密鑰、ssh 密鑰、私鑰等),使用適當(dāng)?shù)碾[私數(shù)據(jù)系統(tǒng);
不要保留任何可部署單元(云服務(wù)、產(chǎn)品或自己的(微)服務(wù))的默認(rèn)憑據(jù);
不要將僅用于測試的代碼或配置放入生產(chǎn);
不要只在服務(wù)中構(gòu)建測試后門;
使用版本控制來記錄配置更改;
使用適當(dāng)?shù)呐渲猛暾詸z查機(jī)制。
錯誤處理
需要考慮的關(guān)鍵事項:
將異常和錯誤視為橫切關(guān)注點,利用面向切面的程序設(shè)計,使用 ControllerAdvices 等類似的工具;
將常見的異常/錯誤(驗證問題、未找到資源、格式錯誤消息)處理邏輯放入到共享庫中,這可以減少(微)服務(wù)之間的交互摩擦;
編寫一個錯誤列表;
使用錯誤代碼(例如 MICRO-4221代表結(jié)構(gòu)驗證導(dǎo)致請求出錯,MICRO-4222 代表業(yè)務(wù)驗證導(dǎo)致請求出錯);
不要在響應(yīng)中泄漏內(nèi)部狀態(tài),避免傳遞 e.getMessage,返回的每個錯誤都必須由其根本原因創(chuàng)建,同時不要泄漏內(nèi)部數(shù)據(jù);
使用 catch-all 機(jī)制,以避免因意外異常而泄漏內(nèi)部狀態(tài)。你可以利用全局錯誤處理程序捕獲異常并返回 500;
所有錯誤都應(yīng)該返回同一個對象,以實現(xiàn)統(tǒng)一的體驗;
在API文檔中使用適當(dāng)?shù)?HTTP 狀態(tài)碼記錄所有的錯誤情況。如果使用 OpenAPI,請記錄所有可能的 HTTP 狀態(tài)碼,即使它們返回相同的 OpenAPI 對象。
分支策略與提交
需要考慮的關(guān)鍵事項:
使用簡單的分支策略,基于trunk的方式、GitHub工作流等,隨便選一個;
存儲庫和分支采用有意義的命名;
使用描述性提交,以方便將來追蹤變更;
分多次提交少量的代碼,以更好地分隔變更;
使用智能提交,即提供指向任務(wù)(來自任務(wù)管理系統(tǒng))的鏈接;
考慮使用預(yù)提交鉤子來驗證提交;
提交消息中不要包含敏感信息;
存儲庫啟用遠(yuǎn)程訪問時需要特別小心,特別是托管在云中的存儲庫。
代碼審查
需要考慮的關(guān)鍵事項:
必須執(zhí)行代碼審查(保持善意和自信,提供具體說明,以及其他良好的習(xí)慣);
機(jī)械的檢查交給工具來做,專心審查功能以及是否符合標(biāo)準(zhǔn)和實踐;
如果你反復(fù)遇到同一個問題,請將其添加到標(biāo)準(zhǔn)中;
建立檢查列表,直到所有人都養(yǎng)成關(guān)注同一個問題的習(xí)慣。
工具與第三方庫
需要考慮的關(guān)鍵事項:
制定引入新工具的流程。進(jìn)行權(quán)衡分析,并推廣到更廣泛的群體,得到所有人的接受/同意,并確保覆蓋更廣泛的情況;
選擇開源軟件時注意許可;
創(chuàng)建許可列表,在其中列出所有無需詢問即可使用的許可、需要討論的許可以及不允許使用的許可;
在發(fā)現(xiàn)新工具/庫/產(chǎn)品時,不要著急使用,你需要考慮:是否穩(wěn)定?是否有良好的維護(hù)?是否有成功案例?
考慮使用 OWASP Dependency Check、License Plugin 之類的工具,或其他更復(fù)雜的工具,例如 Black Duck等;
制定一個普遍認(rèn)可的工具/庫創(chuàng)建列表,供所有人挑選;
定期更新依賴項。
代碼分析
需要考慮的關(guān)鍵事項:
使用一種或多種工具來分析代碼;
必須擁有一種(至少)常見的代碼分析工具,以及一種注重安全實踐的工具;
常見的(Java)代碼分析工具:Sonarqube、PMD、SpotBugs;
常見的安全代碼分析工具:Veracode、Checkmarx、Sonarqube;
你不需要遵循這些工具提供的所有標(biāo)準(zhǔn)規(guī)則(盡管通常這些標(biāo)準(zhǔn)都與行業(yè)建議一致),可以根據(jù)實際情況選出適合自己的規(guī)則。
測試
需要考慮的關(guān)鍵事項:
執(zhí)行各個級別的自動化測試:單元測試、集成測試、組件測試、API測試、端到端測試等;
除了正面測試之外,還需要關(guān)注負(fù)面測試以及邊界測試,CATS 是一款優(yōu)秀的 API 測試工具;
不要忽視失敗的測試,即使是間歇性失敗的測試,其中可能隱藏了嚴(yán)重的潛在問題;
測試必須具有彈性,而且必須充分;
測試必須使用類似且可預(yù)測的方法;
測試不得依賴于復(fù)雜的外部設(shè)置,必須能夠通過模擬依賴項、使用內(nèi)存設(shè)置來完成測試,或采用測試容器,或僅依賴于已部署的(微)服務(wù)。任何其他步驟只會使設(shè)置更加復(fù)雜化;
考慮在管道內(nèi)添加一些安全測試;
考慮突變測試。
CI/CD
需要考慮的關(guān)鍵事項:
在重要的環(huán)節(jié)添加質(zhì)量檢測,并作為檢查點,如果檢測失敗,則構(gòu)建也會失?。?/p>
質(zhì)量檢測必須符合這些標(biāo)準(zhǔn),并自動檢查每個(微)服務(wù);
下面是一個 CI/CD 管道示例:
編譯和構(gòu)建;
檢查格式;
運行測試并檢查覆蓋率;
運行突變測試;
運行代碼分析;
運行安全代碼分析;
檢查第三方庫的漏洞;
檢查第三方庫的許可;
部署;
運行 API 測試;
運行其他類型的測試。
雖然看上去很冗長,但在微服務(wù)上運行這些檢查非??欤?/p>
編寫自己的流水線腳本;
不要將流水線與(微)服務(wù)融合到一起;
使用適合于所有(微)服務(wù)的流水線模板。
認(rèn)證和授權(quán)
需要考慮的關(guān)鍵事項:
不要自行構(gòu)建身份驗證和授權(quán),請使用標(biāo)準(zhǔn)的產(chǎn)品和服務(wù);
所有內(nèi)部與外部API都需要身份認(rèn)證,選擇一些可靠的認(rèn)證服務(wù);
外部和內(nèi)部調(diào)用需要使用單獨的身份驗證和授權(quán)機(jī)制:使用一組憑據(jù)/機(jī)制來驗證外部調(diào)用,再使用另一組單獨的憑據(jù)/機(jī)制來驗證內(nèi)部調(diào)用;
憑據(jù)始終需要加密,無論是否投入了使用;
所有API(無論內(nèi)部還是外部)都需要使用 HTTPS;
不要通過 HTTP GET 接收身份驗證憑據(jù),僅使用 HTTP 頭部或 HTTP POST/PUT;
即使在調(diào)試時也不能記錄憑據(jù),通過日志記錄的catch all來避免記錄憑據(jù);
確保授權(quán)和身份驗證機(jī)制允許細(xì)粒度的控制和管理,即可以限制每個操作的調(diào)用次數(shù)、撤銷訪問、頒發(fā)額外的憑據(jù)等;
考慮使用集中式身份提供程序和公共庫;
對于高度敏感的 API/服務(wù)使用增強(qiáng)的安全控制(API 的雙向 TLS,服務(wù)訪問的 MFA);
使用隨機(jī)數(shù)來防止重放攻擊;
設(shè)計和構(gòu)建采用最低特權(quán)原則。
通用安全實踐
需要考慮的關(guān)鍵事項:
永遠(yuǎn)不要使用自己的加密程序,不要在這個空間內(nèi)重新發(fā)明輪子;
使用行業(yè)推薦算法:AES 256、RSA 2048+、SHA-2 512等;
使用 TLS 1.3+ 來保證傳輸安全;
在執(zhí)行敏感數(shù)據(jù)的加密或散列操作時,必須“加鹽”和/或“加胡椒”,以防止暴力攻擊;
檢查編程語言處理敏感信息的實踐,例如在 Java 中,在處理密碼、銀行卡號、社會保險號時,必須使用 byte,不能使用 String。必須盡量減少數(shù)據(jù)在內(nèi)存中停留的時間并在使用后清除對象。
質(zhì)量
如上所述,系統(tǒng)生命周期的標(biāo)準(zhǔn)和實踐并不一定會直接關(guān)系到安全。質(zhì)量方面也有這個問題。當(dāng)前的設(shè)計和方法缺陷可能會導(dǎo)致應(yīng)用程序宕機(jī),即便并不是由真正的安全問題引起的。
關(guān)于性能,需要考慮的關(guān)鍵事項:
對于昂貴的資源,比如數(shù)據(jù)庫、API等,應(yīng)該使用連接池;
使用線程池;
使用緩存;
操作數(shù)據(jù)時使用適當(dāng)?shù)募希?/p>
如果可以,請使用并行編程;
確保你了解對象關(guān)系映射(ORM)如何生成查詢;
避免將大量資源加載到內(nèi)存,請使用數(shù)據(jù)流;
建立每個(微)服務(wù)實例的性能基準(zhǔn),幫助你了解何時需要擴(kuò)展;
定期執(zhí)行負(fù)載測試與性能測試。
關(guān)于彈性,需要考慮的關(guān)鍵事項:
使用斷路器、重試、超時、速率限制;
當(dāng)依賴的 API 不可用時有明確的回退策略;
關(guān)于彈性的資源:
所有 API 都必須具備冪等性;
不要在(微)服務(wù)實例中存儲狀態(tài),可以考慮使用分布式緩存。
關(guān)于可用性和可擴(kuò)展性,需要考慮的關(guān)鍵事項:
設(shè)計不應(yīng)當(dāng)限制(微)服務(wù)的水平擴(kuò)展;
做好故障計劃,建立自動化的機(jī)制,根據(jù)負(fù)載水平自動伸縮;
考慮分片,只讀副本;
使用多區(qū)域部署。
關(guān)于可觀察性和監(jiān)控,需要考慮的關(guān)鍵事項:
所有(微)服務(wù)都必須公開有關(guān)應(yīng)用程序以及底層容器的健康端點;
健康端點必須返回有關(guān)其所有依賴項的信息:數(shù)據(jù)庫、加密服務(wù)、連接的 API、事件總線等。
利用標(biāo)準(zhǔn)化日志創(chuàng)建有意義的操作儀表板。
自動化
一切都應(yīng)盡可能實現(xiàn)自動化。自動化可以確保預(yù)測性和一致性。應(yīng)該利用 CI/CD 流水線自動化所有檢查,這些檢查將從質(zhì)量的角度評估(微)服務(wù)。對于不適合自動化的標(biāo)準(zhǔn),可以考慮 Semgrep 等工具。
總結(jié)
在本文中,我盡可能地列出了方方面面的實踐建議。雖然這不是一份詳盡的攻略,但可以作為建立安全思維模式的起點。在貫徹完成這些實踐后,你可以進(jìn)一步深入的研究。這些實踐不僅可以確保系統(tǒng)安全,而且還具備結(jié)構(gòu)化與統(tǒng)一性。在快速開發(fā)系統(tǒng)(無論是開發(fā)全新的系統(tǒng)還是改造遺留系統(tǒng))時,這些實踐尤為重要。你不需要從第一天開始就貫徹所有實踐,特別是過多的通用標(biāo)準(zhǔn)會限制你的選擇。你可以逐步嘗試,然后看看效果。
原文鏈接:
聲明:本文由CSDN翻譯,轉(zhuǎn)載請注明來源。
1.《提高(微)服務(wù)安全的非完全攻略》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《提高(微)服務(wù)安全的非完全攻略》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進(jìn)行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/yule/2185207.html