共用方式為


相依性掃描

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

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

關於相依性掃描

相依性掃描會產生任何開放原始碼元件、直接或可轉移的警示,發現程式代碼所依賴的弱點。 直接弱點是您程式代碼直接使用的連結庫。 可轉移的相依性是直接相依性所使用的連結庫或其他軟體。

關於相依性掃描偵測

每當存放庫的相依性圖形變更,以及包含建置新程序代碼之相依性掃描工作的管線之後,就會儲存元件的新快照集(換句話說,新的認可)。

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

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

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

支援的套件生態系統

相依性掃描支援所有支援的套件生態系統的直接和可轉移相依性。

套件管理員 語言 支援的格式
貨運 Rust Cargo.toml, Cargo.lock
CocoaPods \(英文\) Swift Podfile.lock
Go 模組 Go go.mod, go.sum
Gradle (英文) Java *.lockfile
Maven Java pom.xml
npm \(英文\) JavaScript package-lock.json、 、 package.jsonnpm-shrinkwrap.jsonlerna.json
NuGet (英文) C# *.packages.config、 、 *.project.assets*.csproj
pip Python setup.py, requirements.txt
pnpm JavaScript package.json
RubyGems Ruby Gemfile.lock
Yarn JavaScript package.json

關於相依性掃描警示

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

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

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

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

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

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

如果您關閉存放庫的進階安全性,您將無法存取 [進階安全性] 索引標籤和建置工作中的結果。 建置工作不會失敗,但當停用進階安全性時,會以工作執行的任何建置結果,且不會保留。

警示詳細資料

您也可以按下特定警示和補救指引,深入瞭解警示的詳細數據。

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

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

偵測

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

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

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

警示的相依性掃描偵測檢視螢幕快照

嚴重性

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

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

尋找詳細數據

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

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

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

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

管理相依性掃描警示

檢視存放庫的警示

具有存放庫參與者許可權的任何人都可以在 Repos> 進階安全性檢視存放庫所有警示的摘要。

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

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

修正相依性掃描警示

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

修正易受攻擊的可轉移相依性通常採用明確覆寫每個識別直接相依性所使用的易受攻擊元件版本的形式。 一旦根相依性將易受攻擊元件的使用升級為安全版本,您就可以升級每個根相依性,而不是多個個別覆寫。

更新 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",
  }
}

現在,所顯示的 版本取決於的版本eslintpackage.json,該版本acorn是正則表達式阻斷服務 (ReDoS) 弱點,並建議更新至版本或更新版本5.7.4, 6.4.1, 7.1.1。 如果您從相依性掃描工具取得警示,它應該會告訴您需要易受攻擊相依性的根本相依性。

Yarn

如果您使用 Yarn,您可以使用 yarn 來尋找完整的相依性鏈結。

> $ 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.

完整的相依性鏈結為 eslintacornespree>>。 一旦知道相依性鏈結之後,您就可以使用 Yarn 的另一個功能,選擇性相依性解析來覆寫使用的橡子版本。

使用 中的 package.json [解析] 欄位來定義版本覆寫。 顯示三種不同的覆寫封裝方法,最差到最佳:

{
  "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只會覆寫封裝中 封裝中的 espreeeslint 用法acorn。 它特別以易受攻擊的相依性鏈結為目標,而且是覆寫套件版本的建議方式。

npm \(英文\)

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

如果您需要對可轉移的相依性進行特定變更,請新增覆寫。 例如,您可能需要新增覆寫,以已知安全性問題取代相依性版本、將現有的相依性取代為分支,或確定隨處使用相同版本的套件。

{
  "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 的說法,「只覆寫套件中espree封裝中的 eslint 使用量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相依B:2.0.0A:1.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-providercom.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 原因或mvn 相依性:樹狀結構內建,因此查看相依性樹狀結構最簡單的方式通常是流覽 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. 警示狀態會從 [開啟] 變更為 [已關閉] ,並顯示您的關閉原因

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

此動作只會關閉所選分支的警示。 其他可能包含相同弱點的分支會保持作用中,直到採取其他動作為止。 任何先前已關閉的警示都可以手動重新開啟。

針對相依性掃描進行疑難解答

相依性掃描未識別任何元件

如果相依性掃描工作已完成,但未標記任何元件,且無法針對具有已知弱點的元件產生警示,請確定您在工作之前 AdvancedSecurity-Dependency-Scanning@1 有套件還原步驟。

相依性掃描未挑選新的弱點

如果您正在執行新的組建,但未如預期般看到新的弱點,請確定組建是以新的認可執行。

相依性掃描工作逾時

相依性掃描工作在逾時 300 秒或 5 分鐘之前執行的預設時間。 如果工作在完成前逾時,您可以設定管線變數 DependencyScanning.Timeout,其預期整數代表秒數,例如 DependencyScanning.Timeout: 600。 默認逾時 300 秒下的任何項目都沒有任何作用。

若要使用此變數,請新增 DependencyScanning.Timeout 為管線變數:

- task: AdvancedSecurity-Dependency-Scanning@1
- env:
    DependencyScanning.Timeout: 600

建置工作的分鏡案例

如果相依性掃描建置工作封鎖管線的成功執行,而您需要緊急略過建置工作,您可以設定管線變數 DependencyScanning.Skip: true

相依性掃描工作許可權

相依性掃描建置工作會使用管線身分識別來呼叫進階安全性 REST API。 根據預設,相同專案中的管線可以存取擷取警示。 如果您從建置服務帳戶中移除這些許可權,或如果您有自定義設定(例如,裝載在與存放庫不同的專案中的管線),則必須手動授與這些許可權。

將許可權授 Advanced Security: View Alerts 與管線中使用的組建服務帳戶,其中專案範圍的管線為 [Project Name] Build Service ([Organization Name]),而集合範圍的管線為 Project Collection Build Service ([Organization Name])