軟體供應鏈安全已成為現代軟體開發的關鍵議題。SolarWinds 等攻擊事件凸顯了供應鏈的脆弱性,促使業界積極尋求更有效的安全防護措施。Policy as Code (PaC) 作為新興解決方案,能將安全策略以程式碼形式定義和自動執行,有效提升軟體供應鏈的安全性。本文將探討 PaC 如何在軟體開發生命週期的不同階段(如程式碼函式庫、Pipeline、基礎設施即程式碼)中發揮作用,並以 Rego 策略為例,示範如何強化 Dockerfile 的安全檢查,並提出最佳實踐建議,協助企業構建更安全的軟體供應鏈。

PaC與軟體供應鏈安全管理

軟體供應鏈(Software Supply Chain, SSC)包含了開發與交付軟體解決方案的相關活動,這些活動涵蓋了內部使用、商業銷售以及開源軟體(OSS)開發。這些活動經過流程整理與自動化Pipeline處理,負責建構、測試與維護軟體元件。近年來,業界越來越關注如何保護軟體供應鏈,避免因已知或未知漏洞而引發的攻擊與利用。

軟體供應鏈安全現狀

在撰寫本文時,許多新興技術與方法正被用來改善軟體供應鏈的管理。這些技術與方法是根據過往發生的知名軟體供應鏈攻擊事件所衍生出來的經驗。這些攻擊事件提醒我們需要檢視現有的安全措施,並思考如何正確應用政策即程式碼(Policy as Code, PaC)解決方案來偵測甚至預防類別似攻擊。

瞭解正常行為以偵測異常

多年來,網路安全領域一直採用「瞭解正常行為」的方式來偵測異常。過去在評估Kubernetes安全工具時,曾經檢視過一個網路工具,它透過學習Pod的網路行為來偵測可能的異常行為。一旦Pod的網路行為被記錄和特徵化,該解決方案就會對可能的異常網路行為發出警示,甚至隔離被認為「行為異常」的Pod。這種方法在網路安全領域很常見,儘管在當時它對於Kubernetes叢集內部網路來說是新的嘗試。

攻擊行為與正常行為的偏差

網路安全攻擊通常在系統和元件的操作偏離其已知正常狀態(即基線)時被偵測到。2020年的SolarWinds攻擊事件正是如此。這次攻擊始於2019年,當時SolarWinds Orion產品被臭名昭著的Sunspot惡意軟體所感染。Sunspot破壞了Orion的建構流程,並將Sunburst後門引入Orion產品中。

程式碼範例:使用PaC監控軟體供應鏈

policies:
  - name: monitor-ssc
    resource: ssc-components
    filters:
      - type: marked-for-op
        op: update
        # 檢查是否有需要更新的軟體元件
    actions:
      - type: notify
        to:
          - https://example-slack-channel.com/webhook
        # 當發現需要更新的軟體元件時,通知相關人員

內容解密:

此YAML程式碼定義了一個名為monitor-ssc的PaC政策,用於監控軟體供應鏈中的元件。當有軟體元件被標記為需要更新時,該政策會透過Slack頻道通知相關人員。這樣的機制可以及時發現並處理潛在的安全風險。

軟體供應鏈攻擊的防範

為了防範軟體供應鏈攻擊,企業需要建立健全的安全監控機制。這包括但不限於:

  1. 持續監控:對軟體供應鏈中的各個環節進行持續監控,以便及時發現異常行為。
  2. 自動化檢測:利用自動化工具檢測軟體元件的安全性,及時發現已知或未知的漏洞。
  3. 及時更新:對於發現的安全漏洞或需要更新的軟體元件,應及時進行更新或修補。
  4. 事件回應:建立事件回應計畫,以便在發生安全事件時能夠迅速回應和處理。

Mermaid軟體供應鏈安全監控流程

  graph LR;
    D[D]
    A[開始監控] --> B[持續監控軟體供應鏈];
    B --> C[自動化檢測安全漏洞];
    C --> D{發現安全漏洞?};
    D -- 是 --> E[通知相關人員];
    D -- 否 --> B;
    E --> F[進行更新或修補];
    F --> B;

圖表翻譯: 此圖展示了軟體供應鏈安全監控的流程。首先開始監控,接著持續監控軟體供應鏈中的各個環節。透過自動化工具檢測安全漏洞,如果發現安全漏洞,則通知相關人員並進行更新或修補,然後繼續監控。

隨著雲端運算、大資料和人工智慧等技術的不斷發展,軟體供應鏈安全管理將面臨新的挑戰和機遇。企業需要不斷更新和完善其安全管理策略和技術手段,以應對日益複雜和多變的安全威脅。同時,業界也需要加強合作和分享安全知識和最佳實踐,共同提升軟體供應鏈的安全性。

程式碼範例:未來軟體供應鏈安全管理趨勢

import pandas as pd

# 模擬未來軟體供應鏈安全管理資料
data = {
    'Year': [2023, 2024, 2025],
    'ThreatLevel': [8, 9, 10]
}

df = pd.DataFrame(data)

# 預測未來安全威脅等級
def predict_threat_level(year):
    # 簡單線性預測模型
    return df.loc[df['Year'] == year, 'ThreatLevel'].values[0]

print(predict_threat_level(2025))

內容解密:

此Python程式碼模擬了未來軟體供應鏈安全管理的安全威脅等級預測。透過簡單的線性模型,可以預測未來某一年份的安全威脅等級。這種預測有助於企業提前做好安全防範措施。

結語

總而言之,軟體供應鏈安全管理是一個需要持續關注和改進的領域。透過結合PaC解決方案和其他先進技術和方法,企業可以有效地提升其軟體供應鏈的安全性,為業務發展提供堅實保障。同時,業界需要共同努力,加強合作,共同面對和解決軟體供應鏈安全挑戰。

軟體供應鏈的安全性與Policy as Code的應用

軟體供應鏈(Software Supply Chain, SSC)安全性在現代軟體開發中扮演著至關重要的角色。近年來,諸如SolarWinds和Log4Shell等重大安全事件頻發,凸顯了加強SSC安全性的迫切需求。Policy as Code(PaC)作為一種有效的解決方案,能夠在SSC的不同階段實施安全策略,從而提升整體安全性。

SSC安全性的挑戰

SSC涉及多個環節,包括程式碼開發、構建、測試和佈署等。在這個過程中,各種開源和專有軟體元件被整合在一起,形成複雜的依賴關係。這種複雜性使得SSC容易受到各種安全威脅。

  1. SolarWinds事件:駭客在SolarWinds的構建過程中植入了後門程式Sunburst,進而影響了眾多使用SolarWinds Orion軟體的客戶。該事件顯示了SSC安全的脆弱性。

  2. Log4Shell漏洞:2021年發現的Log4Shell漏洞允許遠端程式碼執行(RCE),影響範圍廣泛,包括開源和專有軟體。該漏洞的修復工作量巨大,凸顯了SSC安全的挑戰。

這些事件表明,傳統的安全措施已不足以應對日益複雜的SSC安全挑戰。因此,需要引入新的安全機制,如PaC,以加強SSC的安全性。

Policy as Code在SSC中的應用

PaC是一種將安全策略以程式碼形式定義並自動執行的技術。它可以在SSC的不同階段實施安全檢查和控制,從而提高安全性。

SSC中的策略執行點(PEPs)

在SSC中,有多個策略執行點(PEPs),這些PEPs是實施PaC的關鍵位置:

  1. 程式碼函式庫(Codebase):PaC可以在程式碼提交時驗證程式碼的安全性,例如使用GitHub Actions進行程式碼檢查。

  2. Pipeline(Pipeline):PaC可以驗證Pipeline執行過程中的產物,如靜態應用程式安全測試(SAST)和軟體成分分析(SCA)的輸出結果。

  3. 基礎設施即程式碼(IaC):PaC可以在IaC被應用到環境之前進行驗證,確保基礎設施的安全組態。

  4. 資源環境(Resource Environments):PaC可以驗證雲端或資料中心中的IaaS資源的安全性。

  5. 執行環境(Execution Environments):PaC可以在叢集、虛擬機器或裸機伺服器上驗證和變異請求負載。

  6. 應用程式/API:PaC可以對應用程式和API的輸入請求進行驗證和變異,確保應用層的安全。

程式碼函式庫和Pipeline中的PaC

在程式碼函式庫和Pipeline中,PaC可以透過工具如Conftest實作對各種程式碼產物的自動掃描。Conftest支援多種檔案格式的自動偵測和解析,大大簡化了對不同型別程式碼產物的安全管理。

例如,對於Dockerfile,可以使用PaC檢查是否存在潛在的安全風險,如硬編碼的敏感資訊或不安全的組態:

# Dockerfile.bad
FROM alpine as builder
ENV SECRET_KEY=asdsadasdasdasdasda
ENV AWS_ACCESS_KEY_ID=asdsadasdasdasdasda
ENV AWS_SECRET_ACCESS_KEY=asdsadasdasdasdasda
ADD https://example.com/files/somefile somefile
FROM alpine:latest
WORKDIR /
COPY --from=builder somefile somefile
RUN apk add --no-cache curl=8.4.0 \
    --repository=https://example.com/curl-repo
RUN apk add --no-cache curl=1.24.5

內容解密:

此Dockerfile存在多個安全風險:

  1. 硬編碼敏感資訊SECRET_KEYAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY被硬編碼在Dockerfile中,容易被洩露。
    • 解決方案:使用環境變數或安全的憑證管理機制。
  2. 從不可信來源下載檔案ADD https://example.com/files/somefile somefile 可能會下載惡意檔案。
    • 解決方案:驗證下載檔案的完整性和來源。
  3. 不安全的軟體包管理:使用非官方或不可信的倉函式庫安裝軟體包可能引入安全風險。
    • 解決方案:使用官方或受信任的倉函式庫。

透過PaC,可以自動檢測這些問題並阻止不安全的Dockerfile被構建或佈署。

PaC在SSC中的優勢

  1. 自動化安全檢查:PaC可以在SSC的不同階段自動執行安全檢查,及時發現和修復安全問題。

  2. 統一的安全策略:透過將安全策略以程式碼形式定義,PaC確保了安全策略的一致性和可執行性。

  3. 提高合規性:PaC可以幫助企業滿足各種法規和標準的要求,提高合規性。

策略執行點在軟體供應鏈中的詳細分析

軟體供應鏈(SSC)涉及多個階段,每個階段都有其特定的安全需求。策略執行點(PEPs)是實施Policy as Code(PaC)的關鍵位置,能夠在不同階段進行安全檢查和控制。

程式碼函式庫的安全檢查

在程式碼函式庫階段,PaC可以驗證程式碼的安全性。例如,使用GitHub Actions進行程式碼檢查,可以檢測出潛在的安全問題,如硬編碼的憑證、不安全的函式呼叫等。

name: Code Security Check
on:
  push:
    branches:
      - main
jobs:
  security-check:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Run security check
        run: |
          # 執行安全檢查指令碼
          ./security-check.sh

內容解密:

此GitHub Actions工作流程定義了一個名為Code Security Check的工作,當程式碼推播到main分支時觸發。它會執行一個名為security-check.sh的指令碼來檢查程式碼的安全性。

  • actions/checkout@v2用於簽出程式碼,以便進行檢查。
  • ./security-check.sh是自定義的安全檢查指令碼,可以根據具體需求編寫。

Pipeline中的安全檢查

在Pipeline階段,PaC可以驗證構建產物的安全性。例如,使用SAST和SCA工具分析構建產物,檢測潛在的安全漏洞。

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'make build'
            }
        }
        stage('SAST') {
            steps {
                sh 'sast-tool --analyze build-output'
            }
        }
        stage('SCA') {
            steps {
                sh 'sca-tool --analyze build-output'
            }
        }
    }
}

內容解密:

此JenkinsPipeline定義了三個階段:構建、SAST分析和SCA分析。

  • sh 'make build'命令用於構建專案。
  • sast-tool --analyze build-output命令對構建產物進行靜態應用程式安全測試。
  • sca-tool --analyze build-output命令對構建產物進行軟體成分分析。

圖表翻譯:

  graph LR;
    A[開始] --> B{檢查程式碼安全性};
    B -->|是| C[執行SAST];
    B -->|否| D[拒絕提交];
    C --> E[執行SCA];
    E --> F[佈署];
    D --> G[通知開發者];

此圖表展示了在SSC中實施PaC的基本流程:

  1. 檢查程式碼安全性:驗證程式碼是否符合安全標準。
  2. 執行SAST:對程式碼進行靜態安全分析。
  3. 執行SCA:對構建產物進行軟體成分分析。
  4. 佈署:透過所有檢查後,將產物佈署到生產環境。

隨著SSC的不斷演進,PaC技術也將繼續發展。未來,我們可以期待以下幾個方面的進步:

  1. 更強大的工具整合:PaC工具將與更多的開發和維運工具整合,提供無縫的安全檢查體驗。

  2. 更智慧的安全策略:透過機器學習等技術,PaC將能夠制定更智慧、更動態的安全策略,以應對不斷變化的安全威脅。

  3. 更高的自動化程度:PaC將進一步提高自動化程度,減少人工干預,提高安全管理的效率。

總之,Policy as Code在軟體供應鏈安全中具有廣泛的應用前景。透過在不同階段實施自動化的安全檢查和控制,PaC能夠顯著提高軟體供應鏈的安全性,為企業創造更大的價值。

使用Rego策略強化Dockerfile安全檢查

隨著容器化技術的普及,Dockerfile的安全性越來越受到重視。本文將介紹如何使用Rego策略來檢查Dockerfile中的安全問題,並提供具體的程式碼範例。

為什麼需要檢查Dockerfile?

Dockerfile是用於構建Docker映象的指令碼檔案,其中包含了構建映象所需的指令和引數。一個不安全的Dockerfile可能會導致構建出的映象存在安全漏洞,從而對系統造成威脅。因此,檢查Dockerfile的安全性是非常重要的。

使用Rego策略檢查Dockerfile

Rego是一種用於定義策略的語言,可以用於檢查和驗證各種資料格式,包括Dockerfile。本文將使用Rego策略來檢查Dockerfile中的安全問題。

Rego策略範例

package main

import rego.v1

# 定義可能隱藏秘密的關鍵字
places_where_secrets_hide := {
    "secret",
    "apikey",
    "access",
}

# 定義不良網域
bad_domains := {"example.com"}

# 定義可疑的RUN指令
suspect_runs := {
    "wget",
    "curl",
}

# 檢查ENV指令中是否包含秘密
deny_secrets contains msg if {
    some x in input
    x.Cmd == "env"
    value := x.Value[0]
    some s in places_where_secrets_hide
    contains(lower(value), s)
    msg := sprintf("發現秘密:%q", [value])
}

# 檢查FROM指令是否使用latest版本
deny_latest contains msg if {
    some x in input
    x.Cmd == "from"
    value := x.Value[0]
    endswith(lower(value), "latest")
    msg := sprintf("發現使用latest版本:%q", [value])
}

# 檢查FROM指令是否指定版本
deny_no_version contains msg if {
    some x in input
    x.Cmd == "from"
    value := x.Value[0]
    count(split(value, ":")) == 1
    msg := sprintf("未指定版本:%q", [value])
}

# 檢查RUN apk指令是否指定repository
deny_run_apk_no_repo contains msg if {
    some c in input
    c.Cmd == "run"
    command := c.Value[0]
    subcommand := split(command, " ")[0]
    lower(subcommand) == "apk"
    not contains(lower(command), "--repository")
    msg := sprintf("RUN apk未指定repository:%q", [command])
}

# 檢查RUN apk指令是否使用不良網域
deny_run_apk_bad_domain contains msg if {
    some c in input
    c.Cmd == "run"
    command := c.Value[0]
    subcommand := split(command, " ")[0]
    lower(subcommand) == "apk"
    contains(lower(command), "--repository")
    some d in bad_domains
    contains(lower(command), d)
    msg := sprintf("RUN apk使用不良網域:%q", [command])
}

# 檢查RUN指令是否使用curl或wget下載不良網域的內容
deny_curl_wget contains msg if {
    some x in input
    x.Cmd == "run"
    value := x.Value[0]
    some run in suspect_runs
    contains(lower(value), run)
    some d in bad_domains
    contains(lower(value), d)
    msg := sprintf("RUN指令使用curl或wget下載不良網域的內容:%q", [value])
}

# 檢查ADD指令是否使用不良網域
deny_add_domain contains msg if {
    some x in input
    x.Cmd == "add"
    value := x.Value[0]
    some d in bad_domains
    contains(lower(value), d)
    msg := sprintf("ADD指令使用不良網域:%q", [value])
}

# 檢查ARG指令是否使用不良網域
deny_arg_domain contains msg if {
    some x in input
    x.Cmd == "arg"
    value := x.Value[0]
    some d in bad_domains
    contains(lower(value), d)
    msg := sprintf("ARG指令使用不良網域:%q", [value])
}

使用Conftest執行Rego策略

Conftest是一個用於測試和驗證組態檔案的工具,支援Rego策略。可以使用以下命令執行Rego策略:

conftest test -p docker.rego Dockerfile.bad

執行結果將顯示Dockerfile中存在的安全問題。

Dockerfile安全檢查的最佳實踐

  1. 避免在ENV指令中硬編碼秘密:使用環境變數或組態檔案來儲存敏感資訊。
  2. 指定FROM指令的版本:避免使用latest版本,以確保映象的可重複性。
  3. 檢查RUN指令的安全性:避免使用curlwget下載不可信的內容。
  4. 使用安全的repository:確保RUN apk指令使用的repository是可信的。