72個網(wǎng)絡(luò)應(yīng)用安全實操要點,全方位保護你的Web應(yīng)用
本文轉(zhuǎn)載自微信公眾號「HelloGitHub」,作者Teo Selenius。轉(zhuǎn)載本文請聯(lián)系HelloGitHub公眾號。
對于開發(fā)者而言,網(wǎng)絡(luò)安全的重要性不言而喻。任何一處代碼錯誤、一個依賴項漏洞或是數(shù)據(jù)庫的端口暴露到公網(wǎng),都會有可能直接送你上熱搜。
那么,哪里可以找到詳細的避雷指引呢?OWASP's top 10 清單太短了,而且它更關(guān)注的是漏洞羅列,而非對預(yù)防。相比之下,ASVS 是個很好的列表,但還是滿足不了實際需求。
本文這份清單將介紹 72 個實操要點,讓你全方位保護你的 Web 應(yīng)用程序。各位看官,準備入坑啦!
一、瀏覽器端的威脅防御
1、用且僅用 HTTPS,防范網(wǎng)絡(luò)攻擊
眾所周知,一個安全的應(yīng)用需要對瀏覽器和 Web 服務(wù)器之間的所有連接進行加密。此外,建議禁用一些舊的密碼套件和協(xié)議。使用 HTTPS 時,僅加密網(wǎng)站的“敏感”部分是不夠的。如非這樣,攻擊者可以截獲某個未加密的 HTTP 請求,然后偽造來自服務(wù)器的響應(yīng),返回惡意內(nèi)容。幸運的是,HTTPS 目前是很容易做到的。我們可以通過 Let's Encrypt 免費獲得證書,加上 CertBot 免費續(xù)期。
繼續(xù)我們的清單,下一個是 HSTS 它與 HTTPS 密切相關(guān)。
2、使用 HSTS 和預(yù)加載來保護用戶免受 SSL 剝離攻擊
服務(wù)器可以用 HSTS 或 Strict Transport Security header 來強制進行加密連接。它表示需要一直使用 HTTPS 連接訪問網(wǎng)站。
HSTS 可以防止 SSL 剝離攻擊。所謂的 SSL 剝離攻擊也就是:網(wǎng)絡(luò)上的攻擊者截獲瀏覽器發(fā)出的第一個 HTTP 請求(通常是未加密的),并立即偽造對該請求的回復(fù),假裝是服務(wù)器并將連接降級為明文 HTTP。
值得注意的是,HSTS 僅在用戶至少成功訪問了一次應(yīng)用程序的情況下才能生效。為了克服這個限制,可以把我們的網(wǎng)站提交到 https://hstspreload.org ,這樣,各瀏覽器便可以將我們的域名通過硬編碼寫入到 HSTS 列表中。
如下:
- Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
警告:
在實施 HSTS 時,將會強制進出該網(wǎng)站的所有網(wǎng)絡(luò)請求均被加密,如果網(wǎng)站請求中仍然有純文本,可能無法訪問。所以,先設(shè)置一個小的 max-age 參數(shù)進行調(diào)試,如果一切正常工作,再加大這個值。調(diào)試成功后再加上預(yù)加載 (preload) ,把開啟預(yù)加載保留在最后一步,因為關(guān)閉它是件很麻煩和痛苦的事情。
3、設(shè)置安全 Cookie,保護用戶免受網(wǎng)絡(luò)攻擊
給 Cookie 加上 Secure 屬性。此屬性將防止 Cookie 在(意外或強制的)未加密的連接中泄漏。
Set-Cookie: foo=bar; ...other options... Secure
4、安全生成 HTML 以避免 XSS 漏洞
要避免 XSS(跨站點腳本)漏洞,可以采用下面兩種方法:
- 完全靜態(tài)的網(wǎng)站(例如 JavaScript SPA + 后端API)。避免生成 HTML 問題的最有效方法是根本不生成HTML,如前述方法,當(dāng)然,也可以試試很酷的 NexJS。
- 模板引擎。針對傳統(tǒng)的 Web 應(yīng)用程序,其中的 HTML 大多是在后端服務(wù)器上根據(jù)提供參數(shù)動態(tài)生成的。這種情況下,不要通過字符串連接來創(chuàng)建 HTML 。推薦的做法是使用模板引擎,比如 PHP 語言的 Twig、Java 語言的 Thymeleaf、Python 語言的 Jinja2 等等。
此外,務(wù)必要正確配置模板引擎,從而可以自動對參數(shù)進行編碼,并且不要使用任何可以繞過這種編碼的“不安全”函數(shù)。不要把 HTML 放在回調(diào)函數(shù)、屬性(不帶引號)或 href/src 等諸如此類的地方。
5、安全使用 JavaScript 以避免 XSS 漏洞
要避免 JavaScript 端的 XSS(跨站點腳本)漏洞,切忌將不受信任的數(shù)據(jù)傳遞到可執(zhí)行代碼的函數(shù)或?qū)傩灾?。這類常見的函數(shù)或?qū)傩园ǎ?/p>
- eval、setTimeout、setInterval 等。
- innerHTML,React's dangerouslySetInnerHTML 等。
- onClick、onMouseEnter、onError 等。
- href、src 等。
- location, location.href 等。
6、沙箱處理不可信內(nèi)容,避免 XSS 漏洞
最好是能避免不可信的內(nèi)容,但往往又不能完全避免:例如需要從遠程獲取 HTML 進行展示,或者需要允許用戶用所見即所得的編輯器寫文章,等等。
要避免這些場景中的 XSS(跨站點腳本)漏洞,請首先使用 DOMPurify 清理內(nèi)容,然后在沙箱中進行內(nèi)容呈現(xiàn)。
即使所見即所得的編輯庫聲稱從 HTML 中移除了惡意內(nèi)容,仍然可以通過重新凈化和沙箱來處理,進一步確保安全。
還有一種常見的情況是,我們想在網(wǎng)頁展示廣告等內(nèi)容。這種情況下簡單采用 IFrame 是不夠的,因為 same-origin 策略會允許跨域的 frame 將父級 frame (也就是我們的網(wǎng)站)的 URL 修改為一個釣魚網(wǎng)站。因此,要記住使用 IFrame 的沙箱屬性來避免此種情況的發(fā)生。
7、采用內(nèi)容安全策略,避免 XSS 漏洞
內(nèi)容安全策略(CSP)可以很好地防御 XSS(跨站點腳本)攻擊、點擊劫持攻擊等。所以,一定要用它!默認情況下,CSP 會阻止幾乎所有的危險操作,所以額外的配置越少越好。如下:
- Content-Security-Policy: default-src 'self'; form-action 'self'; object-src 'none'
它允許從 Web 應(yīng)用程序的源代碼加載腳本、樣式、圖像、字體等,但不允許加載其他內(nèi)容。最值得注意的是,它將阻止內(nèi)聯(lián)腳本()的運行,從而更好地預(yù)防 XSS 漏洞。
此外,form-action:'self' 指令可防止在網(wǎng)站上創(chuàng)建惡意 HTML 表單(比如“您的會話已過期,請在此處輸入密碼”類似的表單),并將其提交到攻擊者的服務(wù)器。
無論如何,都不要指定 script-src: unsafe inline ,一旦這樣做,CSP 將形同虛設(shè)。
最后,如果你擔(dān)心 CSP 會影響生產(chǎn)環(huán)境,可以先以 Report-Only 模式進行部署:
- Content-Security-Policy-Report-Only: default-src 'self'; form-action 'self'
8、設(shè)置 HttpOnly 的 Cookie,保護用戶免受 XSS 攻擊
為 Cookie 設(shè)置 HttpOnly 屬性,可以防止 Cookie 被 JavaScript 代碼訪問。一旦跨腳本攻擊發(fā)生,該設(shè)置也會讓黑客更難竊取到 Cookie 信息。當(dāng)然,有些需要被 JavaScript 代碼訪問的 Cookie,就不能做這個設(shè)置了。
- Set-Cookie: foo=bar; ...other options... HttpOnly
9、針對下載功能,合理設(shè)置避免 XSS 漏洞
向用戶提供下載功能時,在 header 中設(shè)置 Content-Disposition: attachment,從而避免 XSS 漏洞。該設(shè)置將禁止在用戶瀏覽器直接渲染文件,從而避免 HTML 或 SVG 格式的下載文件可能引發(fā)的漏洞。如下:
- Content-Disposition: attachment; filename="document.pdf"
假如我們想允許特定的文件(如 pdf)能在瀏覽器端打開,并且也確定這樣是安全的,那么,可以針對該類型文件,將 header 省略掉或是將 attachment 換為 inline。
10、針對 API 響應(yīng),合理設(shè)置避免 XSS 漏洞
反射型文件下載(RFD)攻擊往往通過構(gòu)建一個 URL 從 API 下載一個惡意文件來實現(xiàn)。針對該類漏洞,可采用在 API HTTP 響應(yīng)中返回帶有安全文件名的 Content-Disposition header來防御。
11、利用現(xiàn)有平臺的反跨站請求偽造(CSRF)機制,避免 CSRF 漏洞
為避免反跨站請求偽造漏洞,務(wù)必確保我們所采用的平臺開啟了反跨站請求偽造功能,并確保該配置發(fā)揮了應(yīng)有的作用。
12、驗證 OAuth 身份認證的 state 參數(shù),避免 CSRF 漏洞
有一類與 OAuth 身份認證相關(guān)的跨站請求偽造漏洞是黑客讓用戶不經(jīng)意間采用其賬戶進行登錄。因此,如果有使用 OAuth 身份認證,務(wù)必確保對狀態(tài)(state)參數(shù)的驗證。
13、正確使用 HTTP 協(xié)議,避免 CSRF 漏洞
除了 POST、PUT、PATCH、DELETE 以外,不要使用其它 HTTP 方法進行數(shù)據(jù)更改。GET 請求一般是不包含在反跨站請求偽造機制中的。
14、為 Cookie 設(shè)置同源屬性,避免 CSRF、XS-leak、XSS 漏洞
為 Cookie 設(shè)置 SameSite 屬性。SameSite 能防止大多數(shù)的跨站點請求偽造攻擊,而且還可以防止許多跨站點泄漏的漏洞。
SameSite 屬性有兩種模式:寬松(lax)和嚴格(strict)。
寬松模式可以防止大多數(shù)跨站點計時和跨站點請求偽造攻擊,但對基于 Get 請求的跨站點請求偽造漏洞無效。如下:
- Set-Cookie: foo=bar; ...other options... SameSite=Lax
嚴格模式則可以防止該類基于 Get 請求的漏洞,以及反射型的跨站點腳本漏洞。然而,嚴格模式不適合常規(guī)的應(yīng)用程序,因為它會中斷身份驗證鏈接。如果用戶已登錄某個網(wǎng)站,現(xiàn)在要在新的頁面打開指向該應(yīng)用程序的鏈接,則打開的新頁面將不會為該用戶自動登錄。由于嚴格模式的限制,會話 Cookie 也不會隨請求一起發(fā)送。嚴格模式設(shè)置如下:
- Set-Cookie: foo=bar; ...other options... SameSite=Strict
15、每次登錄創(chuàng)建一個新的會話 ID,防止會話固定攻擊
會話固定攻擊一般是在以下情形發(fā)生:
- 攻擊者將 Cookie(例如 JSESSIONID=ABC123)注入到用戶的瀏覽器中。
- 用戶使用其憑據(jù)登錄,并在登錄請求中提交攻擊者設(shè)置的 JSESSIONID=ABC123 。
- 應(yīng)用程序?qū)?Cookie 和用戶進行身份驗證。
- 與此同時,擁有該 Cookie 的攻擊者也就可以通過該用戶的身份進行登錄了。
為了防止出現(xiàn)這種情況,程序中需要在身份驗證通過后,創(chuàng)建一個新的會話 ID 返回給用戶,而不是驗證可能被動了手腳的 Cookie。
16、合理命名 Cookie,防止會話固定攻擊
難道 Cookie 命名也能影響到網(wǎng)絡(luò)應(yīng)用程序的安全性?確實如此!將 Cookie 采用 __Host-** 的形式來命名,瀏覽器將:
- 不能通過非加密的鏈接訪問該項 Cookie, 從而避免會話固定攻擊以及其它涉及到 Cookie 讀取與寫入的攻擊;
- 不允許子域名重寫該項 Cookie,從而避免來自子域名網(wǎng)站(抑或是被攻陷,抑或本身就是惡意的)的攻擊。
該項設(shè)置示例如下:
- Set-Cookie: __Host-foo=bar ...other options...
17、設(shè)置 Cache-Control header,防止用戶信息被竊取
緩存是將訪問過的網(wǎng)站、下載過的文件全部存儲在硬盤的某個位置,直到有人手動刪除它們。默認情況下,瀏覽器會對頁面的一切內(nèi)容進行緩存,從而加快訪問速度、節(jié)約網(wǎng)絡(luò)帶寬。
要在公共網(wǎng)絡(luò)環(huán)境保證信息安全,我們需要將所有 HTTP 響應(yīng)設(shè)置一個合適的 Cache-Control header,特別是針對非公開的和動態(tài)的內(nèi)容。
該項設(shè)置示例如下:
- Cache-Control: no-store, max-age=0
18、設(shè)置 Clear-Site-Data header,防止用戶信息被竊取
另外一個可以有效保證用戶退出后記錄即被清除的 header 是 Clear-Site-Data 。當(dāng)用戶退出登錄時,可以在 HTTP 請求中攜帶該 header。瀏覽器會清除該域名下的緩存、Cookie、存儲以及執(zhí)行上下文。大部分瀏覽器都支持該 header。
該項設(shè)置示例如下:
- Clear-Site-Data: "*"
19、妥當(dāng)?shù)靥幚?ldquo;退出”,防止用戶信息被竊取
用戶退出登錄后,務(wù)必要對訪問令牌和會話識別碼進行失效處理。這樣,即使攻擊者從訪問歷史/緩存/內(nèi)存等地方獲取到這些信息,它們也不再有效。
此外,如果有單點登錄,切記要調(diào)用單點登錄的退出端口。否則,因為單點登錄會話仍處于活躍狀態(tài),此時的退出將會無效,只要用戶再次點擊“登錄”,即可自動登錄。
最后,清理掉你可能用到過的 Cookie、HTML5 存儲等。上面提到的 Clear-Site-Data 還未被某些瀏覽器支持,所以最好還是手工清除一下。
20、針對 JavaScript 密碼采用 SessionStorage,防止用戶信息被后來者竊取
SessionStorage 類似于 LocalStorage,但對每個標(biāo)簽頁都是獨有的,而且在瀏覽器/標(biāo)簽頁關(guān)閉以后將自動清除。
注意:如果要在系統(tǒng)內(nèi)打開的多個標(biāo)簽頁之間同步用戶的授權(quán)信息,那就需要用事件來同步 sessionStorage 信息。
21、不要通過 URL 傳輸敏感信息
URL 設(shè)計的初衷就不是為了傳輸敏感信息。它會被顯示在屏幕上,存儲到瀏覽器歷史記錄,也容易隨 referrer header 而泄漏,被記錄在服務(wù)器日志等。所以,切忌在 URL 中傳遞敏感信息。
22、采用 Referrer 策略,防止 URL 地址泄露
默認情況下,當(dāng)從系統(tǒng)中鏈接到一個外部網(wǎng)站時,瀏覽器會設(shè)置一個 Referrer 的 header 來告訴該網(wǎng)站此次訪問的來源。這個 header 包含了整個 URL 地址,這可能就涉及到一點隱私。
可以在 HTTP 響應(yīng)中設(shè)置一個 Referrer-Policy 的 header 來禁止該默認行為:
- Referrer-Policy: no-referrer
23、為應(yīng)用設(shè)置獨立域名,防止同源應(yīng)用相互干擾
如果我們這樣設(shè)置應(yīng)用域名:https://www.example.com/app1/ 和 https://www.example.com/app2/,是非常危險的。因為瀏覽器會認為它們是同源應(yīng)用,也就是同樣的服務(wù)主機、端口和模式。正因為是同源應(yīng)用,它們將對彼此有完全的訪問權(quán)限。任何影響其中一個的漏洞都會同樣影響到另外一個。
因此,我們需要給每個應(yīng)用一個獨立的域名。所以,這種情況下應(yīng)該設(shè)置為:https://app1.example.com/ 和 https://app2.example.com/
注意:位于同一個域名下的子域名是可以為整個域名設(shè)置 Cookie 的。例如 app1.example.com 可以為 example.com 設(shè)置 Cookie,而這個 Cookie 也將適用于 app2.example.com。允許為一個站點設(shè)置 Cookie 有時會給會話固定等類型的漏洞以可乘之機。公共后綴列表可以用來應(yīng)對該問題。此外,也可以通過將 Cookie 命名為 __Host- 來防止其被子域名所覆蓋。
24、謹慎采用 CORS(跨域資源共享)
瀏覽器的安全模型大部分是依賴于同源策略,它可以防止應(yīng)用的跨域讀取。而 CORS(跨域資源共享)則是一種允許網(wǎng)站進行跨域資源訪問的手段。所以,決定使用它之前,最好先搞清楚自己是否真的需要。
25、限制請求來源
如果你在 api.example.com 的服務(wù)需要被來自 www.example.com 的 GET 請求訪問,那么可以在 api.example.com 服務(wù)上指定如下header:
- Access-Control-Allow-Origin: https://www.example.com
如果你有個公開的服務(wù)接口(比如說一個提供給互聯(lián)網(wǎng)上 JavaScript 客戶端使用的計算器服務(wù)),那么你可以指定一個隨機的來源:
- Access-Control-Allow-Origin: *
如果你只想讓有限的幾個域名訪問它,那么可以在程序中讀取請求的 Origin header,進行比對后處理。不過,建議使用現(xiàn)成的庫來操作,不要徒手擼,很容易出錯。
26、謹慎使用 allow credentials 選項
默認情況下,跨域資源共享是不帶用戶憑證的。但如果在 Web 服務(wù)器端指定如下 header,則將允許攜帶:
- Access-Control-Allow-Origin: https://www.example.com
- Access-Control-Allow-Credentials: true
這對 header 組合相當(dāng)危險。因為它會使跨域訪問具備已登錄用戶的權(quán)限,并使用該權(quán)限來訪問網(wǎng)站資源。所以,如果你不得不使用它,務(wù)必小心為上。
27、對 HTTP method 進行驗證
僅允許所需要的 HTTP 方法,從而最小化攻擊面。
- Access-Control-Allow-Methods: GET
28、合理使用 WebSockets, 避免反跨站請求偽造等漏洞
WebSockets 迄今還是比較新的技術(shù),技術(shù)文檔較少使用它難免會有些風(fēng)險。所以,采用時務(wù)必要做到以下幾點:
- 對連接進行加密
就像我們應(yīng)該用 https:// 而非 http:// 采用 WebSockets 時也要使用 wss:// 而非 ws://
HSTS 也會影響 WebSockets ,它會自動將非加密的 WebSocket 連接升級到 wss://
- 對連接進行鑒權(quán)
如果使用的是基于 Cookie 的鑒權(quán)機制,且 WebSocket 服務(wù)器與應(yīng)用服務(wù)器在同一個域名下,那就可以在 WebSocket 中繼續(xù)使用已有的會話。不過切記要對請求源進行驗證!
如果不是基于 Cookie ,可以在系統(tǒng)中創(chuàng)建一個單次使用、有時間限制并與用戶 IP 綁定的授權(quán)令牌,用該令牌對 WebSocket 進行授權(quán)。
- 對連接源進行確認
理解 WebSockets 的一個關(guān)鍵點在于要知道同源策略對其是無效的。任何一個能與你的系統(tǒng)建立 WebSocket 連接的網(wǎng)站,在使用 Cookie 鑒權(quán)的時候,都是可以直接獲得用戶信息的。因此,在 WebSocket 握手時,必須要確認連接源??梢酝ㄟ^驗證請求頭中的 Origin 參數(shù)來確認。
如果想要做到雙重保險,可以采用反跨站請求偽造令牌作為 URL 參數(shù)。但針對每個任務(wù)則需要創(chuàng)建一次性的獨立令牌,而不要直接使用反跨站請求偽造令牌,因為后者主要是用來為應(yīng)用的其它部分提供安全保障的。
29、采用 U2F 令牌或客戶端證書,保護系統(tǒng)關(guān)鍵用戶免受釣魚攻擊
如果系統(tǒng)可能會面臨釣魚攻擊的威脅,說人話也就是,“如果存在這樣的可能性:攻擊者創(chuàng)建一個假的網(wǎng)站,騙取管理員/CEO 或其它用戶的信任,從而盜取其用戶名、密碼和驗證碼”,那么就應(yīng)該使用 U2F 令牌或客戶端證書來防止這種攻擊,這樣的話即使攻擊者有了用戶名、密碼和驗證碼也無法得逞。
備注:強調(diào)釣魚防護對于一般用戶而言往往會帶來不必要的麻煩。然而,提供多一種可選項對終端用戶而言也非壞事。此外,向用戶提前告知釣魚攻擊的危險也是非常必要的。
30、針對跨站點泄露進行保護
跨站點泄露是一系列瀏覽器邊信道攻擊。這種攻擊使惡意網(wǎng)站可以從其它 Web 應(yīng)用程序的用戶中推測出信息。
這種攻擊存在已有時日,但是瀏覽器端卻是最近才開始添加針對性的預(yù)防機制??梢栽?這篇文章 中了解關(guān)于該類攻擊的更多細節(jié)以及應(yīng)該采取的安全控制措施。
二、服務(wù)器端的威脅防御
其次,是服務(wù)器端的威脅防御,這里從應(yīng)用系統(tǒng)、基礎(chǔ)設(shè)施、應(yīng)用架構(gòu)、應(yīng)用監(jiān)控、事件響應(yīng)等不同側(cè)面,歸納了如下建議:
2.1 應(yīng)用系統(tǒng)
31、對用戶輸入進行合法性驗證
該類別的措施中最關(guān)鍵的一點就是盡可能嚴格地對所有用戶輸入進行合法性驗證。適當(dāng)?shù)尿炞C會使系統(tǒng)漏洞更難被發(fā)現(xiàn)和利用。對不合法的用戶輸入直接拒絕,而不要嘗試去清洗。驗證方面包括如下:
- 采用嚴格的數(shù)據(jù)類型。針對日期采用 DataTime 類型,數(shù)字采用 Integer 類型等等。針對有固定可選項的情況采用枚舉類型。盡量避免采用字符串類型。
- 如果必須采用字符串,至少給一個長度限制。
- 如果必須采用字符串,將可輸入的字符集盡可能地減少。
- 如果要處理 JSON,使用 JSON 模式進行驗證。
- 如果要處理 XML,使用 XML 模式進行驗證。
32、異常處理優(yōu)雅化,避免技術(shù)細節(jié)泄露
對終端用戶不要顯示堆棧記錄或類似的調(diào)試信息。采用全局的異常處理器對異常進行處理,展現(xiàn)給瀏覽器端簡單的錯誤信息。這樣會使攻擊者更難發(fā)現(xiàn)和利用系統(tǒng)中的漏洞。
33、不要自己做鑒權(quán)
對用戶進行鑒權(quán)時可能會出現(xiàn)各種各樣的問題:要抵御密碼猜想攻擊、用戶枚舉攻擊,要管理密碼重置、存儲用戶憑證,樣樣都不容易。就像密碼處理一樣復(fù)雜,我們普通人還是不要嘗試了。
直接使用 auth0 等類似的工具來進行身份驗證,采用一些廣泛使用的、安全的軟件模塊來實現(xiàn)通信協(xié)議(常見的為 OpenID connect)。如果不想用 auth0 這類第三方的身份提供商,也可以自己搭建一個類似 KeyCloak 的服務(wù)來代替。
34、對一切都進行鑒權(quán),減少攻擊面
應(yīng)用系統(tǒng)要默認對一切都進行鑒權(quán),除非是一些靜態(tài)資源、異常頁面或登出頁面。
35、采用多重身份認證
萬一有人破解了身份認證服務(wù)呢?如果存在這種擔(dān)憂,直接上多重身份認證(說人話也就是:除了密碼以外,還需要手機驗證碼)。這樣就算身份認證服務(wù)被黑、攻擊者可以冒充到任何人,還是無法知道手機收到的驗證碼。
36、通過嚴格的權(quán)限控制,避免對數(shù)據(jù)或功能的未授權(quán)訪問
權(quán)限控制雖不是件容易事,但也有妥善處理的方法:只要時刻記住不要在控制器方法中忘了對用戶權(quán)限進行驗證,從而帶來用戶越權(quán)的漏洞,包括:
- 不要默認對所有控制器方法開通訪問權(quán)限。
- 根據(jù)用戶角色劃分每個控制器的訪問權(quán)限。
- 采用方法級別的安全控制,限制對服務(wù)方法的訪問權(quán)限。
- 采用集中化的權(quán)限管理工具,防止對每條記錄的非授權(quán)訪問。
- 采用前端 Web 應(yīng)用和后臺 API 結(jié)合的架構(gòu),對每個 App 和 API 均采取權(quán)限控制,而不僅是對與互聯(lián)網(wǎng)連接的部分進行控制。
- 為了進一步澄清權(quán)限管理工具,這里總結(jié)了一些要點:
- 數(shù)據(jù)記錄要有可以進行權(quán)限控制的字段,比如 int ownerId。
- 被授權(quán)的用戶要有一個 ID。
- 要有一個類可用來進行權(quán)限評估,在數(shù)據(jù)記錄的 ownerId 與 用戶的 ID 相匹配時,能判斷出用戶具有對應(yīng)的訪問權(quán)限。
- 在以上基礎(chǔ)上,可以將權(quán)限評估類集成到應(yīng)用平臺的權(quán)限控制系統(tǒng)中,比如 Spring Security 產(chǎn)品的 PreAuthorize、PostAuthorize 等等。
- 如果需要更復(fù)雜的權(quán)限控制,也可以搭建一個完善的 ACL 系統(tǒng)。
37、采用合適的工具和技術(shù),避免注入漏洞
注入類的漏洞有很多,而且都很相似,包括 SQL 注入、HTML 注入、XML 注入、XPath 注入、命令注入、SMTP 注入、響應(yīng) header 注入等等。名稱不同但本質(zhì)相同,相應(yīng)地解決方法也類似:
- 問題原因:使用字符串拼接,來構(gòu)建特定協(xié)議下的參數(shù)化消息。
- 解決方案:采用合適的、安全的、現(xiàn)成的工具來實現(xiàn)這項任務(wù)。
這里不會深入太多細節(jié),只要記住:不管你是什么協(xié)議,都謹記上面這點。后面會列舉一些常見的注入類漏洞。
38、創(chuàng)建安全的數(shù)據(jù)庫查詢語句,避免 SQL 注入漏洞
如果要避免 SQL 注入漏洞,那就記住絕不要自己用字符串拼接 SQL 查詢語句。采用一個對象關(guān)系映射框架(ORM)來實現(xiàn),可以讓開發(fā)更高效、應(yīng)用更安全。
如果想要構(gòu)建更細粒度的查詢,可以使用更底層一點的 ORM。
如果不能使用 ORM,那就嘗試預(yù)處理語句,但也要小心這類語句會比 ORM 更容易出現(xiàn)錯誤。
警告:
ORM 框架也不是萬能的,體現(xiàn)在兩方面:一是,它對原生的 SQL 查詢還是支持的,最好不要使用這類查詢;二是,像其它任何軟件一樣,ORM 框架也會時不時被曝出漏洞。所以,還是遵循我們一而再再而三強調(diào)的策略:對所有輸入進行驗證,采用網(wǎng)絡(luò)應(yīng)用程序防火墻(WAF),并保持軟件包的更新,這樣基本就可以放心了。
39、謹慎使用操作系統(tǒng)的命令行,防止命令注入的相關(guān)漏洞
如果可以避免,最好不要執(zhí)行操作系統(tǒng)命令。如果不能避免,那最好遵循以下準則:
- 采用合適的庫/方法來構(gòu)建命令及其參數(shù)。參數(shù)必須是 list 類型。不要用單獨字符串來創(chuàng)建命令。
- 不用使用 shell 來調(diào)用命令。
- 預(yù)定義好命令參數(shù)。比如 curl,如果允許用戶通過 -o 來指定參數(shù),那么攻擊者就有機會寫入到本地文件系統(tǒng)。
- 了解程序如何執(zhí)行,并相應(yīng)地對參數(shù)進行驗證。再比如 curl,你可能只是想讓用戶可以拉取某個網(wǎng)站的內(nèi)容,但如果他拉取了 file:///etc/passwd,那就危險了。
- 想清楚再行動。在上面的例子中,就算驗證了訪問地址是以 http:// 或 https:// 開頭,攻擊者也可以發(fā)起以這兩類協(xié)議開頭的攻擊,如:http://192.168.0.1/internal_sensitive_service/admin。
- 再強調(diào)一遍:真得要想清楚了再行動。就算你對 DNS 進行驗證,確保命令中不含敏感內(nèi)網(wǎng)地址,你有去禁止將特定 DNS 記錄映射到 192.168.0.1 嗎?如果答案是否,那就危險了。
40、合理配置 XML 解析器,避免 XML 漏洞
作為一種標(biāo)記語言,XML 的危險性體現(xiàn)在它可以訪問系統(tǒng)資源。XSLT 的一些實現(xiàn)甚至支持嵌入代碼。因此,在處理時必須非常謹慎。
- 如果可以,避免接受來自不受信任源的 XML/XSLT。
- 如果要向 XML、XSLT 或 XPath 傳參,記住要使用安全的軟件組件,而不要使用字符串連接/格式化的方式。
- 使用主流、安全的軟件組件來解析 XML/XSLT。不要使用錯誤的庫或代碼來處理 XML。此外,在任何情況下,都不要試圖去徒手擼一個解析器(比如 SAML),非常容易出錯。
- 正確配置解析器:禁用 XSLT 文檔、禁用 xinclude、禁用文檔類型定義、禁用外部實體,啟用 DOS 保護。具體配置在實現(xiàn)時會有所不同,但務(wù)必對所選擇的解析器進行深入的研究。
41、采用合適的類構(gòu)建URL,避免 URL 注入漏洞
URL 注入經(jīng)常會在以下情況發(fā)生:
- flavour = request.getParam("flavour");
- url = "https:/api.local/pizzas/" + flavour + "/";
- return get(url).json();
如果 flavour 被設(shè)置為:
- ../admin/all-the-sensitive-things/
那么這個 API 請求將會變?yōu)?https://api.local/admin/all-the-sensitive-things/,是不是很兇險?
解決方案依然是采用合適的 URL 構(gòu)建庫來為 URL 傳參,從而能正確地對參數(shù)進行編碼。
42、采用合適的類構(gòu)建路徑,避免路徑遍歷漏洞
就像 URL 地址一樣,如果攻擊者設(shè)法在路徑中的某個地方偷偷地插入 ../../../ ,文件路徑可能最終指向意料之外的位置。要避免這種情況,請創(chuàng)建一個類,采用這個類安全地構(gòu)造路徑,并驗證最終路徑是否在預(yù)期目錄中。避免在文件路徑中使用不受信任的數(shù)據(jù),或者更好的是,完全避免使用文件系統(tǒng),直接采用云存儲。
43、謹慎采用文件系統(tǒng),接收不受信任的內(nèi)容
如果允許用戶寫入服務(wù)器的文件系統(tǒng),可能會出現(xiàn)各種各樣的問題。改用云存儲,或者在數(shù)據(jù)庫中使用二進制 blob。
如果您必須訪問磁盤,則應(yīng)遵循以下指導(dǎo)原則:
- 不要讓不受信任的數(shù)據(jù)影響內(nèi)部文件路徑。
- 將文件保存在遠離 webroot 的隔離目錄中。
- 在寫入磁盤之前,請驗證文件內(nèi)容是否與預(yù)期格式匹配。
- 正確設(shè)置文件系統(tǒng)權(quán)限以防止寫入不需要的位置。
- 不要提取壓縮包(例如 ZIP),因為它們可以包含任何文件,包括指向系統(tǒng)任意地方的鏈接和路徑。
44、不要動態(tài)執(zhí)行代碼,避免遠程代碼執(zhí)行漏洞
不要使用 eval 或等效函數(shù)。找到一種其它的方法來實現(xiàn)代碼執(zhí)行。否則,不受信任的數(shù)據(jù)將有可能進行函數(shù)調(diào)用,從而在有機會在服務(wù)器上執(zhí)行惡意代碼。
45、合理采用序列化,避免反序列化漏洞
對不受信任的數(shù)據(jù)進行反序列化是很危險的,很容易導(dǎo)致遠程代碼執(zhí)行。
- 如果可以避免,不要使用序列化。
- 如果可以在服務(wù)器端序列化對象,則對其進行數(shù)字簽名。當(dāng)需要再次反序列化它們時,請在繼續(xù)反序列化之前驗證簽名。
- 使用一些主流的軟件組件,并保持更新。許多反序列化庫會一直被發(fā)現(xiàn)漏洞。GSon 是個不錯的選擇。
- 使用簡單的文本格式,如 JSON,而不是二進制格式。此外,應(yīng)該避免像XML這樣有問題的格式,因為這樣除了反序列化之外,還需要擔(dān)心 XML 漏洞。
- 在處理序列化對象之前驗證它。例如:對于 JSON,在繼續(xù)反序列化之前,根據(jù)嚴格的 JSON 模式驗證 JSON 文檔。
2.2 基礎(chǔ)設(shè)施
46、采用網(wǎng)絡(luò)應(yīng)用程序防火墻(WAF)
安裝防火墻,會減少很多風(fēng)險。ModSecurity 就是一個很好的開源選擇。
47、配置 Web 服務(wù)器,避免 HTTP desync 攻擊
HTTP desync,也稱 HTTP 請求走私攻擊,是指攻擊者劫持隨機用戶向系統(tǒng)發(fā)出的 HTTP 請求。這類攻擊一般在以下情況下發(fā)生:
- 前端服務(wù)器,比如負載均衡器或反向代理服務(wù)器,接受攜帶有 Content-length、Transfer-Encoding 等頭部參數(shù)的請求時,將請求未經(jīng)處理隨即傳遞到后臺;
- 后臺接受該請求的服務(wù)器(通常是應(yīng)用服務(wù)器),采用(或被欺騙采用)一個不同于前端服務(wù)器的機制來確定 HTTP 請求從何處開始、何處結(jié)束,比如前端服務(wù)器使用 Content-Length,而應(yīng)用服務(wù)器采用 Transfer-Encoding;
- 前端服務(wù)器重復(fù)利用與后端服務(wù)器的連接;
- 前端服務(wù)器在與后臺服務(wù)器連接時采用 HTTP/1(而非 HTTP/2)。
那么該如何進行防范呢?一般是根據(jù)所采用的產(chǎn)品:
- 咨詢所采用的反向代理產(chǎn)品供應(yīng)商,確保該產(chǎn)品具備主動防范攻擊的能力;
- 配置前端服務(wù)器,在與后臺連接時采用 HTTP/2;
- 配置前端服務(wù)器,防止利用同一個連接發(fā)送多個客戶端的 HTTP 請求;
- 采用網(wǎng)絡(luò)應(yīng)用程序防火墻(WAF),并確保其具備防止請求走私的模塊。
48、采用容器
讓目標(biāo)應(yīng)用隔離其他應(yīng)用來運行。這樣,即使發(fā)生了攻擊事件,攻擊者也不會有權(quán)限去訪問未經(jīng)許可的文件、系統(tǒng)或網(wǎng)絡(luò)資源。因此,最好使用 Kubernetes 或一個云端環(huán)境來部署你的應(yīng)用。如果因為某種原因必須使用一臺服務(wù)器,那么可以手動采用 Docker 來約束應(yīng)用。
49、使用 SELinux/AppArmor
即使通過容器來運行應(yīng)用,也還是需要進一步采用 SELinux 或 AppArmor 策略來進一步地對應(yīng)用做出約束,從而減少容器漏洞引發(fā)的威脅。
50、采用最少權(quán)限的服務(wù)賬戶
這種方法帶來的好處是即使發(fā)生了被攻擊事件,也能減少被攻擊造成的損失。再次重申,列出所有的情形是不可能的,這里僅列舉一些例子幫助大家理解:
- 即使使用了 Docker,甚至是使用了 SELinux/AppArmor,不要用 root 賬戶來運行你的應(yīng)用。為你的應(yīng)用單獨創(chuàng)建一個具備盡可能少的權(quán)限的賬戶,從而降低攻擊者利用容器或內(nèi)核漏洞等進行攻擊的可能性;
- 如果有使用數(shù)據(jù)庫,確保應(yīng)用程序中的數(shù)據(jù)庫用戶在訪問數(shù)據(jù)庫時具備盡可能少的權(quán)限;
- 如果應(yīng)用中集成了 API,確保應(yīng)用訪問 API 時具備盡可能少的權(quán)限。
51、限制外部網(wǎng)絡(luò)連接
攻擊者通常需要建立一定的反向通信渠道來建立操控渠道或竊取數(shù)據(jù)。此外,一些漏洞也是需要外部網(wǎng)絡(luò)連接才會被發(fā)現(xiàn)、被利用。
因此,不能讓應(yīng)用隨便訪問外部網(wǎng)絡(luò),包括 DNS。試下在服務(wù)器運行命令 nslookup www.example.com,如果運行成功,則說明你沒有對外部網(wǎng)絡(luò)連接做出適當(dāng)?shù)南拗?。如何處理此類問題,一般則取決于基礎(chǔ)設(shè)施。
針對外部的 TCP/UDP/ICMP 連接,一般可以通過以下方式禁用:
- 網(wǎng)關(guān)防火墻,如果有的話;
- 如果是老式服務(wù)器,可以采用本地的防火墻(例如 iptables 或 Windows 防火墻);
- 如果服務(wù)器端采用 Docker,可以使用 iptables;
- 如果使用了 Kubernetes,可采用網(wǎng)絡(luò)策略定義。
DNS 處理起來稍微麻煩一點,我們通常需要允許對一些 hosts 的訪問。
- 如果有本地的 hosts 文件,那就很簡單,可以采取上面的任何一種方式來將 DNS 徹底禁用;
- 如果沒有,那么你需要在你上游的 DNS 中配置一個私有的區(qū)域,在網(wǎng)絡(luò)層限制僅能訪問該指定的 DNS 服務(wù)器。這個私有區(qū)域內(nèi)只允許對一些預(yù)先指定的 hosts 的訪問。
52、跟蹤 DNS 記錄,防止子域名劫持
子域名劫持發(fā)生場景舉例如下:
- 假如我們擁有一個域名 example.com;
- 針對一次促銷活動,我們買了另一個域名 www.my-cool-campaign.com ,然后創(chuàng)建了一個別名從 campaign.example.com 映射到 www.my-cool-campaign.com;
- 這次促銷活動結(jié)束后,www.my-cool-campaign.com 域名也到期了;
- 但是,從 campaign.example.com 到 www.my-cool-campaign.com 的別名映射仍存在;
- 如果有人購買了這個到期的域名,那么 campaign.example.com 便可以直接指向該域名;
- 如果攻擊者在 www.my-cool-campaign.com 域名下提供一些惡意內(nèi)容,那么便可以通過 https://campaign.example.com 域名直接訪問到。
因此,需要隨時留意你的 DNS 記錄。如果需要處理的類似情況較多,強烈建議你做一個自動監(jiān)控方案。
2.3 架構(gòu)
53、創(chuàng)建內(nèi)部 API 用來訪問數(shù)據(jù)源
對連接互聯(lián)網(wǎng)的網(wǎng)絡(luò)應(yīng)用程序不應(yīng)該太過于信任。例如,不應(yīng)允許它進行數(shù)據(jù)庫直連。否則,當(dāng)有人攻破應(yīng)用程序時,整個數(shù)據(jù)庫都將面臨威脅。
相反,我們應(yīng)該搭建多組件組成的架構(gòu),例如:
- 我們域名為 www.example.com 的應(yīng)用程序使用 auth0 進行鑒權(quán)。
- 該應(yīng)用程序訪問內(nèi)部 API 服務(wù) api.example.local 時,攜帶被授權(quán)用戶的 token,放在請求頭部的 Authorization 中。
- 位于 api.example.local 的 API 服務(wù)根據(jù)用戶的 token 進行訪問限制,進而根據(jù)被授予的權(quán)限讀寫數(shù)據(jù)庫。
假如現(xiàn)在有黑客想要攻破我們的應(yīng)用程序,即使成功,他也沒有權(quán)限訪問整個數(shù)據(jù)庫,而只是利用某個用戶的 token,進而訪問該 token 所允許訪問的那部分數(shù)據(jù)。
54、內(nèi)部連接也需加密和驗證
不要盲目相信內(nèi)網(wǎng)的安全性,有很多方法可以攻破它。對于系統(tǒng)間的訪問,全部采用 TLS(也就是 HTTPS)進行加密,最好在網(wǎng)絡(luò)和系統(tǒng)兩個層次對連接進行鑒權(quán)。
55、對敏感信息集中管理
如果沒有采用合適的敏感信息管理方案,就很難保持授權(quán)的短期性化、可審計性和秘密性。因此,建議采用 HashiCorp Vault 一類的工具來集中管理密碼、加密 key 等類似信息。
2.4 監(jiān)控
56、收集,分析,報警
集中收集日志到一個獨立系統(tǒng),比如 SIEM(安全信息和事件監(jiān)控系統(tǒng))。在這個系統(tǒng)中,可以在一些表征脆弱性、攻擊的事件發(fā)生時進行報警。當(dāng)嚴重威脅發(fā)生時,可以立即通知相關(guān)人員。
57、收集系統(tǒng)安全事件
最重要的日志來源可能就是系統(tǒng)自身了。當(dāng)有可疑行為發(fā)生時,系統(tǒng)應(yīng)能引發(fā)異常,記錄事件,可能的話,甚至可以自動封鎖可能帶來問題的用戶或IP地址。常見可疑行為包括:
- 輸入值的合法性驗證錯誤(例如,試圖輸入 UI 中不可能提供的值)
- 訪問控制錯誤 (例如,嘗試訪問一條在 UI 中不可能出現(xiàn)的記錄)
- 數(shù)據(jù)庫語法錯誤表示某個人發(fā)現(xiàn)了一處 SQL 注入的脆弱性,這時候可要動作快點采取行動了
- XML 錯誤表示某個人發(fā)現(xiàn)了一處 XML 注入的脆弱性,或者正嘗試利用 XXE(XML 外部實體)脆弱性進行攻擊
- 錯誤請求表示用戶可能發(fā)送了被應(yīng)用拒絕的請求。Spring 框架的 RequstRejectedException 就是一個例子
- 反跨站請求偽造令牌驗證錯誤一般表示有人正嘗試尋找系統(tǒng)中存在的脆弱性
58、收集運行時安全日志
使用運行時安全監(jiān)控工具如 Falco 來對異常系統(tǒng)訪問進行檢測。如果采用了 Kubernetes,那么 Falco 就特別有用。遠程也可以對日志進行收集和監(jiān)控。
59、收集 SELinux/AppArmor 日志
假如我們制定了 SELinux 策略防止向外部的連接,但系統(tǒng)忽然向外部某個網(wǎng)站(例如 burpcollaborator.net)發(fā)起 HTTP 請求,那就需要立刻引起關(guān)注。又或者你的系統(tǒng)嘗試訪問 /etc/passwd。這兩種情況都表示有人已經(jīng)發(fā)現(xiàn)了我們系統(tǒng)中的漏洞。
60、收集 Web 服務(wù)器事件
對 Web 服務(wù)器軟件,至少要對訪問日志和錯誤日志進行收集,收集后發(fā)送到集中式的日志服務(wù)器。在突發(fā)事件響應(yīng)時,這將輔助我們快速理清時間線。
61、收集網(wǎng)絡(luò)應(yīng)用程序防火墻(WAF)日志
如果你像上文推薦使用了網(wǎng)絡(luò)應(yīng)用程序防火墻(WAF),那么也對這個日志進行收集。但不用針對這個日志設(shè)置報警,因為它基本上會收到來自互聯(lián)網(wǎng)各種各樣的問題,而且不部分是你不用擔(dān)心的。
2.5 事件響應(yīng)
62、制定應(yīng)對計劃
一旦對我們的系統(tǒng)進行了監(jiān)控和加固,攻擊者將難以快速定位系統(tǒng)漏洞,即使最終發(fā)現(xiàn),我們也能快速了解情況。
但僅了解情況是不夠的,還需要做出如下準備:
- 快速分析系統(tǒng)日志,了解當(dāng)前狀況和需采取的對應(yīng)措施
- 在應(yīng)用防火墻等產(chǎn)品中,快速對個別 url 地址和參數(shù)做出限制
- 如有需要,快速關(guān)停系統(tǒng)
2.6 開發(fā)管理
63、威脅模型
系統(tǒng)地考慮一下“可能會出現(xiàn)哪些問題”并據(jù)此做出調(diào)整。設(shè)計一個新的系統(tǒng)時,越早開始這一步越好。當(dāng)對系統(tǒng)發(fā)生改變時,再重新梳理一遍這個過程。
例如:
小王:如果攻擊者攻破了我們連接了互聯(lián)網(wǎng)的服務(wù)器,怎么辦?
小陳:那可就完蛋了!
小王:好吧!這就說明我們在這里存在著一個信任關(guān)系,我們認為連接了互聯(lián)網(wǎng)的服務(wù)器是不會被攻破的。我們可以信任這一點嗎?
小陳:未必吧!有一百種可能導(dǎo)致我們的服務(wù)器被黑掉,例如我們代碼中存在的脆弱性,或者依賴中存在的脆弱性,或者是我們 Web 服務(wù)器所安裝軟件的脆弱性。
小王:好吧!那就讓我們打破這層信任關(guān)系。接下來該做些什么呢?
小陳:我們這樣來分解一下系統(tǒng):創(chuàng)建一些內(nèi)部的接口用來實際訪問數(shù)據(jù)庫,由此以來,前端的 Web 服務(wù)器就不能直接訪問后臺的所有東西。
小王:這是個好辦法!除此以外,還有其它什么可能出問題呢?
小陳:嗯,如果黑客攻破了我們的內(nèi)網(wǎng)呢?
小王:那所有東西都要丟失了,因為內(nèi)網(wǎng)里服務(wù)器之間的連接都是未加密的。
小陳:……
這就是威脅模型,它不需要多么復(fù)雜。使用這種方式,來找出系統(tǒng)中可能存在的威脅。
64、源代碼強制審查
通過技術(shù)控制手段,防止代碼未經(jīng)他人審核便提交入庫。這是構(gòu)建安全開發(fā)環(huán)境的基礎(chǔ),因為它可以做到:
- 如果攻擊者攻陷了一個開發(fā)人員的電腦,或者是開發(fā)人員自身企圖發(fā)起攻擊,將不能直接將惡意代碼遷入代碼庫;
- 如果開發(fā)人員的錯誤導(dǎo)致引入了有漏洞的代碼,很可能在被其他人檢查時及時發(fā)現(xiàn)。
65、自動化持續(xù)集成管道,僅允許簡單訪問
開發(fā)人員應(yīng)該有權(quán)限觸發(fā) Jenkins 構(gòu)建,且 Jenkins 權(quán)限配置也僅該如此,不要再允許其它權(quán)限。單個開發(fā)人員應(yīng)該不能在構(gòu)建階段引入任意代碼。當(dāng)然,如果像上文推薦的強制性地采用了代碼審查,Jenkinsfile 也可以保存在版本管理工具中。
66、對 artifacts 進行簽名
如果是構(gòu)建容器鏡像,可以把對鏡像簽名作為構(gòu)建的一步。將簽名密鑰存儲在安全的地方。構(gòu)建階段需要訪問密鑰,但是杜絕將密鑰與 Jenkinsfile 一起存儲在版本管理工具中。更好的方式是將密鑰存儲在 HashiCorp Vault 之類的地方,然后在構(gòu)建時再進行拉取。
67、持續(xù)集成管道中加入靜態(tài)應(yīng)用程序掃描器
在持續(xù)集成管道中使用 SpotBugs 和 Find-Sec-Bugs(或者根據(jù)你所采用的技術(shù)棧進行選擇)之類的工具。它們可以幫你在部署代碼之前發(fā)現(xiàn)已知的漏洞。
此外,也可以作為 IDE 的插件安裝在開發(fā)人員的電腦上,在代碼遷入之前就運行這些工具進行檢查。
68、構(gòu)建時對依賴進行檢查,保證最小的依賴集
應(yīng)用程序中依賴的每個軟件包都是一個風(fēng)險來源。通過依賴,我們拉取了第三人的代碼并在我們的應(yīng)用服務(wù)器上執(zhí)行,所以,必須要搞清楚我們依賴的這個軟件包是什么,為什么會依賴它?
- 保持最小的依賴集;
- 僅使用我們所信任的依賴。它們必須是廣泛使用和廣為人知的;
- 采用構(gòu)建框架,對依賴進行確認。
此外,嚴格控制應(yīng)用服務(wù)器的對外連接,從而避免后門的存在。
69、對依賴進行安全掃描
使用 OWASP 依賴檢查工具對依賴中常見的安全問題進行掃描。除了在持續(xù)集成管道中,也可以在開發(fā)人員的開發(fā)環(huán)境運行這些工具。
70、持續(xù)集成管道對鏡像進行安全掃描
如果采用了容器化技術(shù),可以使用 Trivy 等工具對容器鏡像進行一些常規(guī)漏洞的掃描。
71、自動化部署和簽名驗證
開發(fā)人員可以有權(quán)限到生產(chǎn)環(huán)境中部署,但是權(quán)限范圍應(yīng)該控制在前階段已經(jīng)構(gòu)建和簽名過的特定鏡像,而不是直接訪問生產(chǎn)服務(wù)器。如果是使用 Kubernetes,可以通過 Notary 或開放策略代理來驗證待部署鏡像的簽名。
72、設(shè)置一個安全人員
一個人的精力是有限的。我們不能期望每個開發(fā)人員都精通滲透測試或是安全工程師。正如你不能期望所有的安全專家都是優(yōu)秀的開發(fā)人員一樣。因此,可以在團隊中設(shè)置一個專門關(guān)注安全的人員,主要與開發(fā)人員、架構(gòu)師進行交流,幫助保護我們的應(yīng)用程序并在團隊中傳播安全意識。
三、結(jié)論
保證應(yīng)用程序的安全性,光靠避免漏洞時不夠的,必須全面通盤考慮,主動進行防御。這里對一些主要方法進行了總結(jié):
使用最新版本的的軟件組件來執(zhí)行危險的操作,如身份驗證、訪問控制、加密、訪問數(shù)據(jù)庫或解析 XML,并確保正確配置了這些組件,例如 XML 解析時禁用外部實體。
- 使用平臺提供的安全控制,例如反跨站請求偽造保護。
- 使用 Web 瀏覽器提供的安全控件,如 HSTS、SameSite Cookie 和內(nèi)容安全策略。
- 對安全控制進行集中化處理,特別是身份驗證和訪問控制,從而避免一些遺漏,如在某些控制器方法上忘記對安全進行控制。
- 使用 Web 應(yīng)用程序防火墻,防止應(yīng)用程序漏洞被發(fā)現(xiàn)和被利用。
- 通過限制對文件、網(wǎng)絡(luò)和系統(tǒng)資源的訪問來對應(yīng)用程序進行限制。
- 利用威脅模型發(fā)現(xiàn)架構(gòu)中的威脅,并相應(yīng)進行處理。既包括在源代碼層面對每個開發(fā)人員的源代碼進行安全控制,也包括在架構(gòu)層面對前端 Web 服務(wù)器的安全控制。
- 對系統(tǒng)進行監(jiān)控,制定異常處理預(yù)案。
- 在開發(fā)環(huán)境和持續(xù)集成環(huán)境中使用漏洞掃描程序?qū)Υa、鏡像、依賴進行掃描。
- 對開發(fā)人員、架構(gòu)師等開展安全培訓(xùn),并在團隊中配備一名安全人員。
感謝原作者的翻譯授權(quán):