共用方式為


設定相依性掃描

GitHub Advanced Security for Azure DevOps 中的相依性掃描會偵測原始程式碼中使用的 開放原始碼 元件,並偵測是否有任何相關聯的弱點。 開放原始碼元件中發現的任何弱點會標示為警示。

適用於 Azure DevOps 的 GitHub 進階安全性可與 Azure Repos 搭配運作。 若要搭配 GitHub 存放庫使用 GitHub 進階安全性,請參閱 GitHub 進階安全性

先決條件

類別 需求
許可 - 若要檢視存放庫的所有警示摘要:存放庫的參與者 許可權。
- 若要關閉進階安全性中的警示:專案管理員 許可權。
- 若要管理進階安全性中的許可權:必須是 專案集合系統管理員 群組的成員或擁有 進階安全性: 管理設定 許可權設為 允許

如需進階安全性許可權的詳細資訊,請參閱 管理進階安全性許可權

關於相依性掃描

相依性掃描會對你的程式碼依賴的任何開放原始碼元件(無論是直接的還是間接的)發現的弱點發出警示。 直接弱點是指您的程式碼直接使用的函式庫。 傳遞性相依是指直接依賴所使用的程式庫或其他軟體。

了解如何進行依賴性掃描偵測

每當儲存庫的相依性圖變更或執行包含相依性掃描作業的管線之後,便會儲存您元件的新快照。

針對使用中偵測到的每個易受攻擊元件,元件和弱點都會列在組建記錄中,並在 [進階安全性] 索引標籤中顯示為警示。只有 GitHub 檢閱並新增至 GitHub Advisory Database諮詢會建立相依性掃描警示。 組建記錄包含個別警示的連結,以供進一步調查。 如需有關警示細節的更多資訊,請參閱修正相依性掃描警示的說明。

組建記錄檔也包含每個偵測到弱點的基本資訊。 這些詳細數據包括嚴重性、受影響的元件、弱點的標題,以及相關聯的 CVE。

相依性掃描組建輸出的螢幕快照

如需支援的元件生態系統和版本清單,請參閱 支援的套件生態系統

瞭解相依性掃描警示

Azure DevOps 中 Repos 中的 [進階安全性] 索引標籤是檢視安全性警示的中樞,預設會顯示相依性掃描警示。 您可以依分支、管線、封裝和嚴重性進行篩選。 您可以選取警示以取得詳細數據,包括補救指引。 在此情況下,警報中心不會顯示在 PR 分支上完成掃描的警報。

在存放庫中偵測到易受攻擊的套件時,修正相依性掃描警示通常牽涉到升級至較高的套件版本或移除違規套件。 這種建議適用於直接和可轉移的(或間接)相依性。 在進階安全性標籤中,預設視圖顯示的是存放庫預設分支上的當前警報。

如果重新命名管線或分支,則結果不會有任何影響,最多可能需要 24 小時才會顯示新名稱。

存放庫相依性掃描警示檢視的螢幕快照

當安裝了相依性掃描工作的任何管線之最新組建中不再偵測到易受攻擊的元件時,警示的狀態會自動更新為 Closed。 若要檢視已解決的警示,請使用 State 主要工具列中的篩選,然後選取 Closed

檢視已關閉相依性掃描警示的螢幕快照

如果您關閉存放庫的進階安全性,您會失去 [進階安全性] 索引標籤和建置工作中結果的存取權。 建置工作不會失敗,但當停用進階安全性時,透過此工作執行的任何建置結果會被隱藏且不會保留。

警示詳細資料

您也可以點擊特定的警示,以深入瞭解其詳細數據,並獲取補救指引。

顯示相依性掃描警示詳細數據的螢幕快照

區段 說明
建議 建議文字直接來自我們的弱點數據提供者 GitHub Advisory Database。 通常,指引會建議將已識別的元件升級至不可控制的版本。
地點 位置 區段詳細說明相依性掃描工作探索使用中易受攻擊元件的路徑。 如果檔案可以從基礎組建掃描解析為來源中認可的檔案,[位置] 卡片會顯示為可點選的連結。 如果檔案是當做組建的一部分產生(例如組建成品),則無法點選連結。 檢閱組建記錄,以進一步瞭解元件如何帶入組建。
描述 描述是由 GitHub Advisory 描述所提供。

偵測結果

在「偵測」選項卡下所列出的管線是發現易受攻擊元件的管線。 每個數據列都會詳細說明受影響管線的最新組建,以及第一次導入封裝的日期。 如果某些管線中已修正易受攻擊的套件,但並非全部,您會看到部分固定的數據列。

未修正的警報相依性掃描偵測視圖的螢幕快照

解決警示之後,警示會自動移至 Closed 狀態,且 [偵測] 索引標籤示下的最新執行管線會顯示綠色複選標記,這表示包含更新元件的程序代碼已在該管線中執行:

嚴重性

GitHub Advisory Database 提供 CVSS 分數,然後透過下列指導方針將警示轉譯為低、中、高或嚴重嚴重性:

CVSS 分數 嚴重性
1.0 < 分數 < 4.0
4.0 < 分數 < 7.0 中等
7.0 < 分數 < 9.0
Score >= 9.0 重大

尋找詳細數據

在 [尋找詳細數據] 底下通常會找到兩個區段:易受攻擊的套件和根相依性。 易受攻擊的套件是可能易受攻擊的元件。 根相依性區段包含負責導致弱點之相依性鏈結的最上層元件。

如果易受攻擊的套件只參考為直接相依性,您只會看到「易受攻擊套件」一節。

如果易受攻擊的套件同時參考為直接和可轉移的相依性,套件會顯示在「易受攻擊套件」和「根相依性」區段中。

如果易受攻擊的套件僅參考為可轉移的相依性,套件會顯示在「易受攻擊套件」一節中,而參考易受攻擊套件的根相依性會顯示在「根相依性」區段中。

管理相依性掃描警示

檢視存放庫的警示

根據預設,警示頁面會顯示存放庫預設分支的相依性掃描結果。

警示的狀態會反映預設分支和最新執行管線的狀態,即使警示存在於其他分支和管線上也一樣。

修正相依性掃描警示

直接相依性是指您在存放庫中擁有的組件。 可轉移或間接相依性是直接相依性所使用的元件。 不論在直接或可轉移的相依性中找到弱點,您的專案仍然很脆弱。

修正易受攻擊的傳遞相依性通常以明確覆寫用於每個識別出的直接相依性的易受攻擊元件版本的形式進行。 一旦根相依項目將其使用的易受攻擊元件升級為安全版本,您就可以升級每個根相依項目,而不必進行多個個別覆寫。

更新 Yarn/Npm 的相依性

假設此套件有兩個弱點。 一個是針對 axios 的直接相依性,另一個是針對 acorn 的轉移性相依性(也稱為間接相依性或相依性的相依性)。

{
 "name": "my-package",
 "version": "1.0.0",
 "dependencies": {
   "axios": "0.18.0",
   "eslint": "5.16.0",
 }
}

目前的 版本 axios拒絕服務 (DoS) 弱點 ,建議更新至 v0.18.1 或更高版本。 因為它是直接相依性,因此您可以選擇您使用的axios版本,您只需要更新您提取的axios版本即可。 更新後的 package.json 看起來類似:

{
  "name": "my-package",
  "version": "1.0.0",
  "dependencies": {
    "axios": "0.19.2",
    "eslint": "5.16.0",
  }
}

現在,在 package.json 中顯示的 eslint 版本取決於具有正則表達式拒絕服務(Re-DoS)漏洞的 acorn 版本,建議更新至版本 5.7.4, 6.4.1, 7.1.1 或更高版本。 如果您從相依性掃描工具收到警示,它應該會告訴您是哪個根本相依性需要此易受攻擊的相依性。

紗線

如果您使用 Yarn,您可以使用 yarn why 來尋找完整的相依樹。

> $ yarn why acorn
 yarn why v1.22.4
 [1/4] Why do we have the module "acorn"...?
 [2/4] Initialising dependency graph...
 [3/4] Finding dependency...
 [4/4] Calculating file sizes...
 => Found "acorn@6.4.0"
 info Reasons this module exists
   - "eslint#espree" depends on it
   - Hoisted from "eslint#espree#acorn"
 info Disk size without dependencies: "1.09MB"
 info Disk size with unique dependencies: "1.09MB"
 info Disk size with transitive dependencies: "1.09MB"
 info Number of shared dependencies: 0
 Done in 0.30s.

完整的相依性鏈結為 eslint>espree>acorn。 一旦了解相依鏈結後,您就可以使用 Yarn 的另一個功能,選擇性解析相依性,來覆寫所使用的 Acorn 軟體版本。

使用 package.json 中的「resolutions」欄位來定義版本覆寫。 展示三種覆寫封包的方法,從最差到最佳排列:

{
  "name": "yarn-resolutions",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": {
    "axios": "0.19.2",
    "eslint": "5.16.0"
  },
  "resolutions": {
    // DO NOT USE!
    "**/acorn": "6.4.1",
    // BETTER
    "eslint/**/acorn": "6.4.1",
    // BEST
    "eslint/espree/acorn": "6.4.1"
  }
}

使用**/acorn模式將覆寫所有相依套件中 acorn 套件的所有使用方式。 這是危險的,並在運行時失效,所以我們在 Yarn v2 將其移除。

eslint/**/acorn使用 模式會覆寫 eslint 套件下 acorn 套件的所有使用方式,以及它相依的任何套件中。 它比覆寫所有相依性的套件更安全,但如果套件的相依性圖形很大,它仍然會有一些風險。 當有許多子套件使用易受攻擊的套件時,為個別子套件定義覆寫是不切實際的,建議使用此模式。

使用eslint/espree/acorn模式只會覆寫acornespree封裝中eslint封裝的用法。 它特別以易受攻擊的相依性鏈結為目標,而且是覆寫套件版本的建議方式。

npm

如果您使用 npm 8.3 或更高版本,您可以使用 package.json 中的 overrides 字段。

如果您需要對過渡性相依進行特定變更,請新增一個覆寫設定。 例如,您可能需要使用已知的安全性問題覆蓋相依性版本,將現有的相依性替換為分支版本,或確保每個地方都使用相同版本的套件。

{
  "name": "npm-overrides",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": {
    "axios": "0.19.2",
    "eslint": "5.16.0"
  },
   "overrides":{
       "eslint": {
        "espree": {
          "acorn": "6.4.1"
        }
    }
   }
}

顯示的覆寫範例展示了 npm 表達「只在eslint套件中覆寫espree套件中acorn的用法」的方式。這種方法特別針對易受攻擊的相依鏈,亦是覆寫套件版本的建議方式。 覆寫是 npm 的原生功能。 它提供一種方式,將相依樹中的套件替換為另一個版本,或完全換成其他套件。

設定覆寫之後,您必須刪除 package-lock.jsonnode_modules ,然後再執行 npm install 一次。

除非您的相依性和覆寫本身共用完全相同的規格,否則您可能不會為直接相依的套件設定覆寫。例如,假設 axios: "0.18.0" 很脆弱,而我們想要升級至 axios: "0.19.2"。 直接變更相依性版本,而不是使用覆寫。

{
  "name": "npm-overrides",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": {
    "axios": "0.18.0"
  },
  "overrides": {
    // BAD, will throw an EOVERRIDE error
    // "axios": "0.19.2",
  }
}

更新相依性的版本,而不設定覆寫:

{
  "name": "npm-overrides",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": {
    "axios": "0.19.2"
  }
}

更新 Maven 的相依性

相依性解析機制不像 Yarn 中使用的機制那麼複雜。 因此,您只能在專案中有單一版本的相依性。 為了解決此問題,Maven 會使用「最接近的勝利」演算法。 也就是說,它會在相依性樹狀結構中使用最接近專案需求的相依性版本。

例如,您有下列相依性圖表:

your-project --- A:1.0.0 --- B:2.0.0
      \
       \__ B:1.0.0

your-project依賴A:1.0.0,而A:1.0.0又依賴B:2.0.0,但您的專案也直接依賴B:1.0.0。 因此,您的相依性圖表中有兩個不同的相依性 B 版本,但相依性 B 1.0.0 版會因為專案「最接近」而獲勝。

在某些情況下,如果版本相容,此案例可能會運作。 不過,如果 A:1.0.0 相依於 B 的某些功能,該功能僅適用於版本 2.0.0 ,則此行為無法運作。 在最壞的情況下,此專案可能仍會在運行時間進行編譯,但失敗。

讓我們看看真實世界範例。

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.microsoft.customer360</groupId>
  <artifactId>maven-dependencies</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>maven-dependencies</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>com.fasterxml.jackson.jaxrs</groupId>
      <artifactId>jackson-jaxrs-json-provider</artifactId>
      <version>2.10.3</version>
    </dependency>
</project>

假設您所依賴的com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider版本依賴一個com.fasterxml.jackson.core:jackson-databind版本,而該版本存在對不受信任數據的反序列化漏洞

您可以使用 Maven 相依性插件來驗證此相依性。 在這裡情況下,您會執行 mvn dependency:tree -Dincludes=com.fasterxml.jackson.core:jackson-databind 並取得下列輸出:

> $ mvn dependency:tree -Dincludes=com.fasterxml.jackson.core:jackson-databind
 [INFO] Scanning for projects...
 [INFO]
 [INFO] ------------< com.microsoft.customer360:maven-dependencies >------------
 [INFO] Building maven-dependencies 1.0-SNAPSHOT
 [INFO] --------------------------------[ jar ]---------------------------------
 [INFO]
 [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ maven-dependencies ---
 [INFO] com.microsoft.customer360:maven-dependencies:jar:1.0-SNAPSHOT
 [INFO] \- com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:jar:2.10.3:compile
 [INFO]    \- com.fasterxml.jackson.jaxrs:jackson-jaxrs-base:jar:2.10.3:compile
 [INFO]       \- com.fasterxml.jackson.core:jackson-databind:jar:2.10.3:compile
 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD SUCCESS
 [INFO] ------------------------------------------------------------------------
 [INFO] Total time:  0.928 s
 [INFO] Finished at: 2020-04-27T14:30:55+02:00
 [INFO] ------------------------------------------------------------------------

首先,檢查是否有新版的 com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider 並且不依賴易受攻擊版本的 com.fasterxml.jackson.core:jackson-databind。 如果是,您可以升級 com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider 並停止該處。 如果沒有,請覆寫 com.fasterxml.jackson.core:jackson-databind 的版本。

如代碼片段所示,在使用 Maven 時,「以最接近者為準」,所以解決方法是直接將修補弱點的相依性新增至 com.fasterxml.jackson.core:jackson-databind

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.microsoft.customer360</groupId>
  <artifactId>maven-dependencies</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>maven-dependencies</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>com.fasterxml.jackson.jaxrs</groupId>
      <artifactId>jackson-jaxrs-json-provider</artifactId>
      <version>2.10.3</version>
    </dependency>
    <!-- Dependency resolutions -->
    <!-- jackson-jaxrs-json-provider -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.10.4</version>
    </dependency>
  </dependencies>
</project>

您可以再次執行 mvn dependency:tree -Dincludes=com.fasterxml.jackson.core:jackson-databind 來驗證解決方案是否有效。

$ mvn dependency:tree -Dincludes=com.fasterxml.jackson.core:jackson-databind
[INFO] Scanning for projects...
[INFO]
[INFO] ------------< com.microsoft.customer360:maven-dependencies >------------
[INFO] Building maven-dependencies 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ maven-dependencies ---
[INFO] com.microsoft.customer360:maven-dependencies:jar:1.0-SNAPSHOT
[INFO] \- com.fasterxml.jackson.core:jackson-databind:jar:2.9.10.4:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.827 s
[INFO] Finished at: 2020-04-27T14:32:42+02:00
[INFO] ------------------------------------------------------------------------

建議您在相依性解析附近新增批注,以便稍後任何人知道相依性為何存在。 一旦根相依性使用新版本,就可以移除它;否則,您會累積相依性。

在實際專案中,盡可能在鏈中更高的層級添加相依性。 例如,您可以在父 POM 檔案中新增解析度,而不是在每個專案 POM 檔案中個別新增解析度。

更新 NuGet 的相依性

NuGet 中使用的相依性解析演算法類似於 Maven,因此只能使用單一版本的相依性。 不過,NuGet 不會固定相依性版本。

例如,如果您有相依性 <PackageReference Include="A" Version="1.2.3" />,您可能會預期此套件相當於 = 1.2.3,但實際上表示 >= 1.2.3。 若要釘選確切的版本,您應該使用 Version="[1.2.3]"。 如需詳細資訊,請參閱 NuGet 版本範圍檔

除了預設範圍行為之外,NuGet 也會還原最低適用的版本以滿足某個範圍。 此行為表示在許多情況下,您必須定義範圍。

讓我們看看此範例專案,其相依於 Microsoft.AspNetCore.App

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <RootNamespace>NuGet.Dependencies</RootNamespace>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.14" />
  </ItemGroup>
</Project>

取決於Microsoft.AspNetCore.Http.Connections的某個版本,而該版本存在遠端程式碼執行(RCE)漏洞

首先,您應該檢查是否有更新版本的 Microsoft.AspNetCore.App 取決於較新版本的 Microsoft.AspNetCore.Http.Connections。 如果是這樣,您可以升級 Microsoft.AspNetCore.App 並在此停止。 如果沒有,您必須覆蓋它所依賴的版本 Microsoft.AspNetCore.Http.Connections

NuGet 沒有內建等同於 yarn 的 why 或 mvn 的 dependency:tree 的功能,所以查看相依性樹狀結構最簡單的方式通常是造訪 nuget.org。如果您瀏覽 NuGet 頁面 Microsoft.AspNetCore.App,您會看到它相依於 Microsoft.AspNetCore.Http.Connectionsversion >= 1.0.4 && < 1.1.0。 或者,在 NuGet 版本範圍中,代表性語法為 [1.0.4,1.1.0)

Microsoft.AspNetCore.Http.Connections 中的 RCE 弱點已在版本 1.0.15 中修正,因此您需要調整版本範圍為 [1.0.15, 1.1.0)

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <RootNamespace>NuGet.Dependencies</RootNamespace>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.8" />
  </ItemGroup>

  <ItemGroup Label="Dependency Resolutions">
    <!-- Microsoft.AspNetCore.App -->
    <PackageReference Include="Microsoft.AspNetCore.Http.Connections" Version="[1.0.15,1.1.0)" />
  </ItemGroup>
</Project>

建議您在相依性解析附近新增批注,以便稍後任何人知道相依性為何存在。 一旦根相依性使用新版本,就可以移除它。 否則,您會累積相依性。

如果沒有可用的修正程式,該怎麼辦?

當沒有已知的修正可用時,下列選項可作為其他補救方法,直到有升級的元件可用為止:

  • 停止使用元件,並將它從程式碼中移除 - 此移除將在安裝相依性掃描工作的新組建中偵測到。
  • 提供一個修正給元件本身。 如果您的組織有關於開放原始碼貢獻的特定指導方針,請遵循這些指導方針。
  • 解除警示。 不過,沒有已知修正的警示仍會對組織造成安全性威脅。 我們建議您不要因為沒有已知的修正而關閉警示。

關閉相依性掃描警示

若要關閉警示,請執行下列步驟:

  1. 移至您想關閉的警示,然後點選該警示。

  2. 選取 [關閉警示] 下拉式清單。

  3. 如果尚未選取,請選取 [已接受風險][誤報] 作為關閉原因。

  4. 在 [批注] 文本框中新增選擇性批注

  5. 選取 [ 關閉 ] 以提交並關閉警示。

  6. 警示狀態會從 Open 變為 Closed,並顯示您解除狀態的原因。

    顯示如何關閉相依性掃描警示的螢幕快照

此動作會解除所有分支的警示。 也會關閉包含相同弱點的其他分支。 先前關閉的任何警示都可以手動重新開啟。

管理拉取請求的相依性掃描警示

如果在拉取請求中為新的程式碼變更建立警示,警示會在拉取請求的 概觀 索引標籤的批註區段中報告為批註,並在存放庫的 進階安全性 索引標籤中作為警示。拉取請求分支可以使用新的分支選擇器條目。

您能看到受影響的套件清單,查看發現的摘要,並在概觀區段中處理批注。

作用中相依性提取要求批注的螢幕快照。

若要解除 Pull Request 警示,您必須瀏覽到警示詳細資訊檢視,以關閉警示並解決註解。 否則,只要變更批注狀態 (1) 即可解析批注,但不會關閉或修正基礎警示。

已關閉相依性提取要求批注的螢幕快照。

若要查看提取要求分支的整個結果集,請流覽至 [Repos>進階安全性],然後選取您的提取要求分支。 在註釋上選取 [顯示更多詳細數據 ],會將您導向 [進階安全性] 索引卷標的 [警示詳細數據] 檢視。

提示

只有在受影響的程式代碼行與提取要求的目標分支相比,提取要求差異完全是唯一的時,才會建立批注。