之前我們已經介紹了 DevSecOps 的方法論與理念,裡面提到了開發流程的五個階段可以導入哪些資安項目。

我們今天要提的就是開發流程裡面的設計階段(Design Phase)、建構階段(Build Phase)和部署階段(Deploy Phase),也就是大家較熟悉的 CI/CD。

將資安導入 CI/CD 中

我以前看過加入資安的 CI/CD,是綠盟科技部落格提到的黃金管道概念。

下面這張圖和綠盟科技文章裡的黃金管道類似。不過面對真實企業環境,我都會根據現有的開發流程來設計,畢竟根據現在的環境來調整和整合,才能讓資安更融入並且增加效果。

ci-cd

先來看一個基本的 CI/CD 流程:

一般 CI 流程會是:功能設計(Design)、開發、CI 測試、程式碼審查(Code Review),最後才會合併(Merge)程式碼。

合併程式碼後,接著 CD 會:在測試環境中部署、進行測試、最後才會真正推到產品線上。

其中,增加和資安有關的項目是:

  • CI 部分
    • 資安系統架構設計(Security Architechture Design)
    • 運行時自我保護(RASP,Runtime Application Self Protection)
    • 靜態應用程式安全測試(靜態測試,SAST,Static Application Security Testing)
    • 資安程式碼審查(Security Code Review)
  • CD 部分
    • 軟體組建分析(SCA,Software Composition Analysis)
    • 動態應用程式安全測試(動態測試,DAST,Dynamic Application Security Testing)
    • 交互式應用程式安全測試(IAST,Interactive Application Security Testing)

來跟大家說明每個部分的「目標」、「常見問題」和「可能的實作方法」。

我們接下來舉的例子,如果你的(新創)公司是:使用敏捷開發流程、擁有開發能力的科技公司、有數名資安工程師的團隊、喜好新技術、傾向使用開源工具等等,也許可以參考看看。

需要先聲明的是實作方法會「因環境而異」,就如前面提到的,「根據環境來調整和整合」,我相信會是不錯的做法。

當然有時候砍掉重練也不錯 … 就看你專業的判斷了:)

在 CI 裡導入資安

資安在 CI 會比較專注在「系統設計」和「程式碼檢測」的部分:

資安系統架構設計(Security Architechture Design)

開發前的功能設計和系統設計,最常見需要被考慮的像是「存取控制(Access Control)」和「機密資訊管理(Secret Management)」等等。

問題:資安人力不足

通常設計時會需要資安人員一起做架構規劃,但這是一個吃人力的部分。你有多個產品線在跑,但你的資安人員人數可能無法負擔所有產品線。

作法:資安分享與培訓

有時候「與其做一個資安功能,不如把功能做得更安全」;與其需要額外的資安人員,不如讓大家在設計時,都意識到要考慮資安。

為了讓資安融入在一般功能裡,我們可以持續給員工做資安分享和培訓、或是由上而下、由內而外的推動,並且讓各個產品的工程師都意識到要考慮基本的資安,可以讓資安人員更專注在核心架構的資安上。

運行時自我保護(RASP,Runtime Application Self Protection)

RASP 像是「淋巴球」,目的是讓產品上線後,有基本「自我保護」的功能。

像是網站如果提供搜尋的功能 query=123,但攻擊者可能會嘗試改成 query=123' and '1'='1,這時候網站可以主動判斷疑似遭受攻擊並且即時防禦。

問題:實作不易、需要花錢買資安產品

有時在原有的功能或架構下,很難開發 RASP 自我保護的功能。且也可能實作完成後影響到整體系統複雜度。

且大部分 RASP 的解決方案都是購買資安產品,獨立實作 RASP 很難做得完整。

作法:難改的用 WAF,新系統使用基本的 RASP

「網站應用程式防火牆(WAF,Web Application Firewall)」就像是「口罩」抵擋病菌。

對於本身無法增加免疫系統的服務,我們可以為它們「戴口罩」。你可以使用像 ModSecurity 或是雲端服務提供的 WAF。

而對於新系統、新架構,我們可以在開發時嘗試把基本的 RASP 考慮進去。像是判斷注入攻擊,可以馬上反應處理、並且將請求內容記錄在不同日誌檔上備查。

靜態應用程式安全測試(SAST,Static Application Security Testing)

在開發者開發完功能後、把程式碼推上遠端時,通常會自動觸發 Jenkins 進行基本程式碼掃描(像 Linter),這部分很適合再加上基本的 SAST 靜態測試工具。像是掃 Python 弱點的 Bandit、掃 Go 弱點的 Gosec 等等,你也可以參考 OWASP 列的靜態測試工具列表

而靜態測試的目的是至少有個資安底線(Baseline),檢測出基本資安問題。

問題:假訊息太多

SAST 只會「看」程式碼有沒有問題,而不會真的「執行」。所以最大的缺點,就是「它很容易看錯、誤以為有問題(False Positive)」。但在這個階段,工程師是很頻繁推程式碼上遠端的,不能老是噴假的資安訊息給工程師、或是每次掃描要花費好幾小時。

作法:嚴重的優先、過濾與回報機制

所以在 SAST 的困難點在於:「要怎麼做到快速且精準?」這是 SAST 的關鍵。如果先定義好基本的威脅模型(Threat Model),並且有完整的過濾與回報機制的話,對優化 SAST 有很大的幫助。

資安程式碼審查(Security Code Review)

問題:耗費人力

程式碼審查也是一個耗費人力的部分,如同「資安系統架構設計」,與其每次都需要額外的資安人員審查,不如讓大家在審查時都考慮到資安。

作法:由內而外

讓大家都考慮到基本的資安問題,這樣可以讓資安人員專注在一些重點資安項目,將資安人力更專注在需要高度安全的功能上。

在 CD 裡導入資安

而 CD 會針對「環境」和「配置」,以及「動態檢測」等等:

軟體組建分析(SCA,Software Composition Analysis)

通常在 CD 部署前,都會包好環境設定,像是程式碼相依的第三方函式庫(3rd Party Library)、容器的映像檔(Image)等等。

但在幾乎每天都爆出「常見弱點與漏洞(CVE,Common Vulnerabilities and Exposures)」的年代,你怎麼知道你用的第三方軟體沒有漏洞?

所以這部分針對的是第三方套件的「已知弱點」掃描。為了自動化檢查這些第三方套件,我們在建構好映像檔後,就可以先做基本的掃描。

而這類的工具其實很多,像是針對容器弱點的 Clair、針對作業系統套件的 Vuls、針對 JS 函式庫的 Retire.js、和適用 Go、Python、Ruby 等語言函式庫的 Snyk

有些靜態工具甚至可以拉到 SAST 一起進行,不需要等到部署時才檢測。

問題:資訊量太多

SCA 有一個大問題是相依性套件太多(像是 JS 的 node_modules),用工具掃完可能會噴出一大堆問題,但可能是屬於低風險或不在威脅範圍內的風險(Out of Scope)。

作法:敏捷、自動化、過濾與回報

最好的方式是根據敏捷開發的特色,快速且持續升級更新。或是跟 SAST 解決偽陽性方法一樣,需要定義基本的威脅模型、和完整的過濾與回報機制。審查這些相依性還需要知道這些第三方套件「被用在哪裡」,資安人員和開發人員合作,才能更精準地判斷威脅。

動態應用程式安全測試(DAST,Dynamic Application Security Testing)

QA 會對測試環境進行測試,DAST 就是加強資安測試的部分。

大家應該都會用 sqlmap 這個家喻戶曉的工具來測試 SQL 注入,不過其實還有像 Arachni 這樣整合性的工具,也是一個很有名的 DAST 工具之一。

問題:測試項目龐雜且耗時

如果不優化動態工具的參數,掃一個較大的網站可能一個禮拜都掃不完。

因為測試項目實在非常多,常用的測試項目標準會是 OWASP Testing Guide,根本無法跟上敏捷開發的速度。

且在產品規格不穩定的情況下,寫測試自動化的效果其實也不高。很容易今天測完,下週就不用測了(產品功能已經砍掉了)。

作法:從核心開始、從穩定開始、從高風險開始

我自己經驗是「不要測試所有資安項目」,從「高風險」的功能先下手。前提是你必須先有基本威脅模型,才能知道什麼是真正高風險。

從最需要資安的地方、核心的功能開始下手,並且以「自動化」和「可持續重複使用」的測試為優先,所以需要從穩定的功能下手。

交互式應用程式安全測試(IAST,Interactive Application Security Testing)

DAST 的掃描耗時,其中一個原因在於它大部分的測試是在「瞎猜」。而 IAST 是 DAST + SASTDAST + RASP 的結合,目的是讓 DAST 動態瞎猜時能有回饋的互動(Interactive),提升精準度。

像是玩終極密碼,從 0 ~ 100 挑一個數字。如果沒有任何回饋,就只能從 0 開始一個一個猜到 100。但如果每次都告訴你「比你猜得數字大、或小」,你就很容易在幾局內猜中數字。

問題:通常是資安產品、需要代理服務

目前一些開源工具還沒有完整做 IAST 的,大部分都是資安產品。IAST 通常會需要一個代理服務(Agent)在後端收集資訊進行反饋,或是會依照程式語言的特性來進行探測。

作法:評估是否購買資安產品

畢竟 IAST 很難由自己團隊獨立做起來,但對於新創,花更多金錢在資安產品上要更謹慎評估,需要考量功能面、需求面都極度需要資安,並且對人力成本、時間成本有考量的話,轉換在金錢成本上購買 IAST 也許是一種解決方法。

從何開始?

靜態測試(SAST)第三方函式庫掃描(SCA)來嘗試導入資安,我覺得會是不錯的開始。

畢竟這類工具多、而且也接近我們平常使用的 Linter 或靜態掃描工具。比較需要注意的是也許「不用一開始就直接整合在 CI/CD 中」,畢竟 SAST 實在太容易噴一堆偽陽性的資訊。

可以先以不要擾民開始:先試用 SAST 工具、挑出幾個高嚴重性問題、再將這幾個高嚴重性(且高精準度)的測試整合進 CI/CD 中。

把準備階段做更好

五個階段分別是:

  1. 準備階段(Preparation Phase)
  2. 設計階段(Design Phase)
  3. 建構階段(Build Phase)
  4. 部署階段(Deploy Phase)
  5. 執行階段(Run Phase)

你會發現在 CI/CD 中加入資安,還需要先準備很多事情,像是威脅模型、資產(Assets)清點等等。

不過不要緊,我們可以發揮快速疊代的精神,不用一次就把威脅模型做到好,我們可以持續修改、持續改進這個模型,並且持續修正 CI/CD 每個階段的資安項目。

接著也許還可以朝著「自動化過濾」、「建置回報平台」前進。盡可能降低人工過濾資安問題,讓整串流程自動化起來。

而動態測試也可以逐漸加入,雖然加入資安測試不是件容易的事,我們之後再來跟大家介紹。

這篇文列舉了很多要做的事情,但說實在不一定每個環節我們都要 100% 實作。「你也許不需要金庫,但可能會需要把門上鎖」,你可以挑選適合自己的資安作法和工具,至少可以讓你默默避免掉一些無謂的災難。

上一篇關於忘記密碼的文章持續有收到大家的想法,十分感謝也很開心可以跟大家討論。如果這些文章對你有幫助,記得要來我們底下的粉專連結按讚和追蹤,一起掌握資安新思維。