ShiftLeft 學習筆記(一)

一 基本聲明

    本文是對shiftleft的一個基本翻譯,幫助大家瞭解、學習這個東西。(嚴謹轉載!歡迎討論!)

二 基本介紹

What is ShiftLeft? 

ShiftLeft是爲開發人員構建的下一代代碼分析平臺。

它的代碼屬性圖(CPG)將應用程序的控制流、程序依賴項和抽象語法樹描述爲一個單一的數據結構,使您能夠從根本上理解應用程序的每個版本的功能,並找到可能帶來風險的任何場景。

快速在Linux/macOS和Windows學習基本的ShiftLeft。

For windows users

本教程向您展示如何使用ShiftLeft安裝、設置、配置和運行您的第一個代碼分析。

1 註冊一個ShiftLeft帳戶

系統將提示您創建一個組織。爲您的組織提供一個名稱,然後單擊Create organization繼續。記錄組織ID和訪問令牌

作爲一個新的ShiftLeft用戶,您將看到一個步驟列表,您需要完成這些步驟才能在儀表板中安裝和設置ShiftLeft。如下圖:

2 安裝檢查

2.1要安裝Inspect,請下載sl.exe.

解壓下載的文件,並運行新解壓的可執行文件開始安裝過程,確保授予安裝程序請求的權限。這將sl.exe複製到C:\Program Files\ShiftLeft

2.2安裝 Protect

如果您想在Inspect之外安裝Protect, ShiftLeft提供了. net框架的安裝程序。您必須使用具有管理員權限的帳戶才能使用Windows安裝程序。

步驟1:下載安裝程序

獲取.net框架安裝程序

Invoke-WebRequest -URI https://cdn.shiftleft.io/download/installer-dotnet-framework-latest-windows-x64.zip -UseBasicParsing -OutFile sl-latest-windows-x64.zip

安裝程序將所有依賴項捆綁到一個可下載的文件中。這使得安裝程序可以在不需要訪問Internet的情況下運行。

步驟2:解壓縮下載的文件並運行安裝程序

獲得安裝程序後,解壓縮下載的文件。

運行新解壓的可執行文件來開始安裝過程。請務必授予安裝程序請求的權限。

安裝程序將Protect複製到C:\shiftleftDotNetAgent,在安裝過程中,您將在命令提示窗口中看到狀態更新。流程完成後,按Enter完成並關閉窗口。

命令行安裝選項:(當從命令行運行安裝程序時,請注意安裝程序二進制文件有以下命令行選項可用來修改默認行爲。)

選擇 描述
--no-prompt 如果從命令行運行安裝程序,則禁用非交互式使用提示
--install-directory 指定安裝目錄;在Windows程序文件夾中,默認值是shiftleft
--start-menu-entries 設置已創建的開始菜單項所在的目錄。在開始菜單的頂層,默認值爲ShiftLeft。如果爲空,則不創建開始菜單項
--sl-home 標識ShiftLeft產品的主目錄。此目錄是作爲安裝過程的一部分創建的,並存儲下載的二進制文件和配置文件。主目錄中默認爲.shiftleft
--no-dotnet-agent 只安裝ShiftLeft Inspect(即sl.exe),而不安裝ShiftLeft Protect

所有目錄都存儲在Windows註冊表中。

3 使用ShiftLeft CLI進行身份驗證

ShiftLeft CLI命令sl auth用於使用ShiftLeft進行身份驗證,並將您的應用程序與您的組織關聯起來。

sl auth --org "YOUR_ORG_ID" --token "YOUR_ACCESS_TOKEN"

您可以從添加應用程序下的ShiftLeft儀表板獲取YOUR_ORG_ID和YOUR_ACCESS_TOKEN的值。

這一步完成了兩件事:使用ShiftLeft的API將您機器上運行的CLI與您的ShiftLeft帳戶鏈接起來(調用該API需要包含令牌)。

可以證實或更新您的身份驗證值在任何時間檢查配置文件位於C:\Users\ {USER} \ .shiftleft \ json。

4 檢查您的代碼

此時,您就可以運行Inspect了。在本教程中,我們將測試HelloShiftLeft,這是一個使用Java構建的演示應用程序,用於演示ShiftLeft如何工作。必須安裝Java 8才能使用HelloShiftLeft。

要獲得ShiftLeft,您可以通過運行來克隆它的repo,在命令提示符中;

git clone https://github.com/ShiftLeftSecurity/HelloShiftLeft.git

克隆了repo之後,通過運行cd HelloShiftLeft導航到該文件夾。

通過運行mvn clean package來使用Maven構建應用程序(您也可以使用您選擇的另一個構建工具)。如果成功,您可以期望將構建成功消息打印到命令提示符)。

運行ShiftLeft使用;

"C:\Program Files\ShiftLeft\sl.exe" analyze --app HelloShiftLeft --java target/hello-shiftleft-0.0.1.jar

您將看到以下輸出:

根據打印到終端的指令,在5-10分鐘後打開提供的URL。這將帶您進入Dataflows頁面;在右上角,單擊“漏洞”查看代碼中出現的問題。

三 Inspect(windows)

3.1 Getting start

本教程向您展示如何安裝、設置和配置Inspect。(一部分內容同 二)

Inspect Your Code

此時,您就可以運行Inspect了。請參閱與您的應用程序相關的特定於語言的頁面:

C#、Go、JavaScala

Analyzing Application

一旦您已經安裝並使用ShiftLeft進行了身份驗證,就可以使用Inspect來分析用以下語言編寫的應用程序。

C#、Go、Java、JavaScript、Scala

識別祕密和熱點

Inspect還可以用於識別應用程序中硬編碼憑據和安全敏感函數的存在。

(這兒提供了不同編程語言的模塊,我們以Java爲例進行介紹)

Java

本文向您展示瞭如何分析用Java編寫的應用程序。它假設您已經安裝並使用ShiftLeft進行了身份驗證。

1 要求:Inspect支持對用Java 7到Java 11編寫的應用程序進行分析。

您的構建環境必須具有:

本地安裝Java 8(根據您的應用程序開發需要,您可能需要同時運行多個Java版本)

至少有16Gb的可用內存

2 構建您的應用程序

Inspect的代碼分析是在已編譯的應用程序字節碼上執行的(而不是在源代碼上)。因此,在使用Inspect分析應用程序之前,必須先構建應用程序。

您可以考慮的一些構建工具包括Maven、Gradle、sbt等。

3 分析Java應用程序

要分析Java應用程序,請運行:

sl analyze --app <name> --java [<path>]
參數 描述
--app <name> 要分析的應用程序的名稱
--java 標識應用程序語言的標誌
[<path>]

要分析的應用程序的.jar或.war文件的位

如果您使用的是類似JavaServer Pages (JSP)這樣的模板框架,那麼所分析的.jar / .war文件中就包含了這些模板。

4 內存

在運行代碼分析時,我們建議使用堆大小,其中包括額外的20%,以確保服務器上有足夠的物理內存來滿足其他需求(例如,Java)。

爲此,我們建議設置一個名爲SHIFTLEFT_JAVA_OPTS的進程環境變量(例如,SHIFTLEFT_JAVA_OPTS=“-Xmx10g”),該變量允許運行ShiftLeft來設置特定應用程序所需的堆內存。

5 CPG模式(代碼屬性圖模式)

您可以選擇使用代碼屬性圖(CPG)模式來分析您的應用程序。使用CPG模式,ShiftLeft在本地構建CPG,然後將其(而不是應用程序的代碼)上傳到ShiftLeft雲進行分析。

要使用CPG模式分析應用程序,請在sl分析命令中包含選項——CPG(sl analyze --app <name> --java --cpg <path>)

Working with Insight Parameters for Inspect

在使用Inspect分析代碼時,您可以修改流程,以便掃描查找硬編碼的憑據和安全敏感函數,並報告發現的內容以及已識別的任何其他漏洞。這是通過在您的sl分析命令中包含附加的Insights參數來實現的。

定義:當ShiftLeft掃描您的代碼以查找硬編碼的憑據時,它將查找硬編碼的值(例如,客戶端機密信息、用戶名/密碼組合)和敏感信息(例如,電話號碼和地址)。

掃描安全敏感函數和硬編碼憑據:若要查找所有硬編碼憑據和安全敏感函數,請將--inspect-next添加到sl analyze命令行。

查找硬編碼憑證:--insights="secrets"

尋找安全敏感的函數:--insights="hotspots"

查找安全敏感函數和硬編碼憑據:--insights="secrets,hotspots"

例如,要在JavaScript應用程序中查找硬編碼憑證和安全敏感函數,可以發出以下sl analyze命令:

sl analyze --js --no-cpg --insights="secrets,hotspots" -app yourAppName <path-to-your-app-directory>

查看你的結果

所有被ShiftLeft標識爲存在於您的應用程序中的硬編碼憑據和安全敏感函數都將出現在“漏洞儀表板”中。

CI/CD Integrations

ShiftLeft支持Inspect與您選擇的持續集成和持續部署工具的集成,以提供自動化的代碼分析。要將Inspect添加到您的構建和部署工作流中,請參閱您正在使用的工具的適當說明:Azure DevOps Bamboo Jenkins CircleCI Docker GoCD TeamCity Jira Travis

Vulnerabilities API

您使用漏洞API來查詢關於代碼漏洞的數據。漏洞是代碼庫中潛在的可利用路徑。

該API按組織或應用程序版本返回一個漏洞列表,其中包含所有必要的信息,以便您對可開發的代碼區域採取行動。

對API請求進行身份驗證:任何公共API請求都需要通過將一個公共API令牌以以下形式:

Key: Authorization
Value: Bearer <your_token>

要獲取令牌,請查看配置文件並複製在Public API Token部分提供的令牌。

一個API返回的例子

{
    "vulnerabilities": [
       {
           "applicationId": "project1549413585aa",
           "vulnerability": {
               "firstDetected": "041718202019.28",
               "vulnerabilityId": "database-write/e0ec210246d63ea44e28c01ed6113a66",
               "category": "a1-injection",
               "title": "Unsanitized database write in `DataLoader.run`",
               "description": "Attacker-controlled data is used in a database query without any sanitation or encoding. This could be intended behavior and thus has a low score. Injection flaws, such as SQL, NoSQL, OS, and LDAP injection, occur when untrusted data is sent to an interpreter as part of a command or query. By injecting hostile data, an attacker may trick the interpreter into executing unintended commands or accessing data without proper authorization which can result in data loss, corruption, or disclosure to unauthorized parties, loss of accountability, denial of access or even a complete host takeover.",
               "score": 1,
               "severity": "LOW_IMPACT",
               "securityEvents": "1",
               "blockedEvents": "1",
               "calls    ": "1",
               "locationURL": "/account/{accountId}/addInterest",
               "locationMethod": "addInterest",
               "status": "FIXED",
               "assignedTo": "[email protected]",
               "dataFlow": <dataFlowObject>
           }
       }
       ],
       "nextPageBookmark": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NTczNTE3NDAsImlhdCI6MTU1NzM1MDg0MCwiaXNzIjoiU2hpZnRMZWZ0Iiwib3JkZXJfYnlfZGlyZWN0aW9uIjoxLCJpbmNsdWRlX2NhbGxzIjp0cnVlLCJDcmVhdGVkQXRCb29rbWFyayI6MTU1NzM0NDc3OH0.VzENvpKuho5iu4KT5R285PC033RPBAaq6xoqFSXg4uJQp1OTElcBYN6EOtunfE3ByahJqgigMXKFxSQ6GIti8AogQc0uQwJvtl6D3HPGvFvpIKdMDu3I77LpoaSMJXIaT3sb03Js78pEnUw0JyMhLBcwXjiC2lycEEWb5TE4zvgP5HE7uwPDTtObJeFQjmQq2fcQOqXFL_PbU2aISA9qgE9OdmX2bqX1my0YcvM0GnaCdNwAddWmvAngoz7GvSW8Uozxeqrs6JXGmHrSGoF4QWvW8klnBv8V92o5CazJuiW_O1nvFK4Yw1mA3ywbtmp6hERYF5EJ_uhx3RXv2YR2dw"
指標 描述
applicationId 組織內每個應用程序的唯一標識。
firstDetected UNIX時間戳的日期和時間,當ShiftLeft第一次檢測到這個漏洞。
vulnerabilityId 此應用程序中此特定漏洞的唯一ID。
category 脆弱性OWASP類別。
title 漏洞標題
description 漏洞描述。
score 漏洞浮動評分,從1到9,代表OWASP的嚴重程度。
severity LOW_IMPACT、MEDIUM_IMPACT和HIGH_IMPACT表示由ShiftLeft分配的分數級別。
securityEvents 脆弱端點的安全相關事件計數。
blockedEvents 被阻塞的安全相關事件的計數。
calls 對脆弱端點的調用總數。表示常規流量和任何檢測到的攻擊。
locationURL 受影響端點的發佈位置。
locationMethod 脆弱代碼路徑的啓動方法。
status UI可配置狀態的漏洞(即。受讓人,固定或忽略狀態等)
assignedTo 個人的電子郵件地址分配修復或分流此漏洞。
dataFlow 觸發漏洞的數據流的詳細信息,包括源函數和目標。

nextPageBookmark:包含要傳遞到相同端點以獲得下一頁結果(如果存在的話)的書籤的字符串。

Pagination

ShiftLeft漏洞API端點始終分頁。結果顯示在最多包含50個結果的連續頁面中。結果顯示在三個類別根據嚴重程度。分頁信息以nextPageBookmark的形式提供給每個響應訪問下一頁,每個頁面的生命週期爲15分鐘。

{
      "vulnerabilities": [],
      "nextPageBookmark": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ...TGkubZyC69DRg",
     "totalResults": "155",
      "lowImpactResults": "104",
    "mediumImpactResults": "21",
    "highImpactResults": "30"
}

組織漏洞列表(組織的歷史記錄漏洞?)

使用以下請求按組織返回漏洞:

POST /api/v3/public/org/{organization id}/vulnerabilities/

結果返回帶有以下標準的漏洞:

  • Belonging to the latest analyzed version of any app

  • Of any severity

  • Of any category

  • With any description

  • With or without calls

  • With or without blocked calls

  • Arbitrarily sorted

  • Only the first page (50 results)

過濾組織的漏洞:您可以在查詢的主體中過濾返回

{
"query": {
        "orderByDirection": "VULNERABILITY_ORDER_DIRECTION_DESC",
        "applicationId": [
            "project1549413585aa"
        ],
        "statusFilter": [
            "VULNERABILITY_STATUS_UNKNOWN", "VULNERABILITY_STATUS_FIXED", "VULNERABILITY_STATUS_IGNORED", "VULNERABILITY_STATUS_ASSIGNED"
        ],
        "severityFilter": [],
        "typeFilter": "",
        "assignedToFilter": [],
        "returnRuntimeData": true,
        "hasRuntimeData": true
    }
  "pageBookmark": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NTczNTE3NDAsImlhdCI6MTU1NzM1MDg0MCwiaXNzIjoiU2hpZnRMZWZ0Iiwib3JkZXJfYnlfZGlyZWN0aW9uIjoxLCJpbmNsdWRlX2NhbGxzIjp0cnVlLCJDcmVhdGVkQXRCb29rbWFyayI6MTU1NzM0NDc3OH0.VzENvpKuho5iu4KT5R285PC033RPBAaq6xoqFSXg4uJQp1OTElcBYN6EOtunfE3ByahJqgigMXKFxSQ6GIti8AogQc0uQwJvtl6D3HPGvFvpIKdMDu3I77LpoaSMJXIaT3sb03Js78pEnUw0JyMhLBcwXjiC2lycEEWb5TE4zvgP5HE7uwPDTtObJeFQjmQq2fcQOqXFL_PbU2aISA9qgE9OdmX2bqX1my0YcvM0GnaCdNwAddWmvAngoz7GvSW8Uozxeqrs6JXGmHrSGoF4QWvW8klnBv8V92o5CazJuiW_O1nvFK4Yw1mA3ywbtmp6hERYF5EJ_uhx3RXv2YR2dw"
}
參數 描述
orderByDirection VULNERABILITY_ORDER_DIRECTION_DESC或VULNERABILITY_ORDER_DIRECTION_ASC應用於漏洞的第一個檢測字段。
applicationId 如果包含,則只返回這些應用程序id的結果。
statusFilter 如果存在,則只返回具有這些狀態的漏洞的結果。
severityFilter 如果存在,只返回這些嚴重漏洞的結果。
typeFilter 如果存在,則匹配人類可讀的漏洞類型。
assignedToFilter 如果存在,只返回已分配給傳遞的電子郵件的漏洞。
returnRuntimeData 真正的默認。指示securityEvents、blockedEvents和調用作爲結果的一部分返回。注意,使用這些參數會使查詢返回速度變慢。
hasRuntimeData 錯誤的默認。指示只應返回端點具有調用的漏洞。

pageBookmark:如果存在,查詢將被忽略,並且如果存在此書籤所指示的查詢的下一頁將被返回,這是可選的。

列出應用程序的漏洞:(檢測的應用程序的漏洞)

您可以使用下面的請求來返回應用程序的漏洞:

POST /api/v3/public/org/{organization id}/app/{application id}/vulnerabilities/

結果返回帶有以下標準的漏洞:

Belonging to the latest analyzed version this app.、Of any severity、Of any category、With any description、With or without calls、With or without blocked calls、Arbitrarily sorted、Only the first page (50 results)

要獲取特定應用程序版本的結果,請使用:

POST /api/v3/public/org/{organization id}/app/{application id}/version/{version}/vulnerabilities

過濾應用程序的漏洞

{
"query": {
        "orderByDirection": "VULNERABILITY_ORDER_DIRECTION_DESC",
        "statusFilter": [
            "VULNERABILITY_STATUS_UNKNOWN", "VULNERABILITY_STATUS_FIXED", "VULNERABILITY_STATUS_IGNORED", "VULNERABILITY_STATUS_ASSIGNED"
        ],
        "severityFilter": [],
        "titleFilter": "",
        "assignedToFilter": [],
        "returnRuntimeData": true,
        "hasRuntimeData": true,
        "vulnerabilityId": "database-write/e0ec210246d63ea44e28c01ed6113a66"
        },
        "pageBookmark": ""
}
參數 描述
orderByDirection VULNERABILITY_ORDER_DIRECTION_DESC或VULNERABILITY_ORDER_DIRECTION_ASC應用於漏洞的第一個檢測字段。
applicationId 如果包含,則只返回這些應用程序id的結果。
statusFilter 如果存在,則只返回具有這些狀態的漏洞的結果。
severityFilter 如果存在,只返回這些嚴重漏洞的結果。
titleFilter 如果存在,漏洞標題部分匹配。注意,使用此參數會使查詢返回速度變慢。
assignedToFilter 如果存在,只返回已分配給傳遞的電子郵件的漏洞。
returnRuntimeData 真正的默認。指示securityEvents、blockedEvents和調用作爲結果的一部分返回。注意,使用這些參數會使查詢返回速度變慢。
hasRuntimeData 錯誤的默認。指示只應返回端點具有調用的漏洞。
vulnerabilityId 如果存在,只有由它識別的漏洞將被返回,這是一種使一個永久鏈接到一個漏洞的方法。

pageBookmark:如果存在,查詢將被忽略,並且如果存在此書籤所指示的查詢的下一頁將被返回,這是可選的。

How to Tag Inspect Results with the Git Branch Name

Inspect允許您提供分支名稱,以便您能夠區分一個分支與另一個分支的分析結果。

在Inspect生成的結果中包含分支信息

從版本控制系統獲取分支名稱。例如,Git允許您使用Git rev-parse——addrev-ref HEAD1來實現這一點。

將在上一步中獲得的分支名稱添加到使用——tag選項自動運行Inspect的腳本中(sl analyze --tag branch=<branchname>)

此時,ShiftLeft將在儀表板中顯示來自代碼分析的結果時包含分支名稱。

Integrating Inspect into the GitHub Pull Request Workflow

本文概述瞭如何將ShiftLeft集成到GitHub工作流中,以便在創建新的Pull Request (PR)時自動檢查分析代碼,CircleCI構建應用程序。ShiftLeft分析過程是構建後的工作。

要求:我們假設您有CircleCI和GitHub帳戶,並且使用Git作爲源代碼的版本控制系統;如果您更喜歡使用Jenkins而不是CircleCI,請參考下面的視頻瞭解使用說明:https://docs.shiftleft.io/shiftleft/inspect/pr-workflow

步驟1:創建GitHub存儲庫

您將需要一個包含源代碼的GitHub存儲庫,並且您的存儲庫應該包含.circleci/config。CircleCI在構建應用程序時查找的yml文件。

Inspect的分析是一個構建後的工作,您可以通過包含ShiftLeft Orb將此功能添加到您的CircleCI工作流中。如果這是您第一次使用第三方Orb,那麼您需要選擇使用第三方Orb。

步驟2:向CircleCI提供您的ShiftLeft憑據

請確保您已經創建了SHIFTLEFT_ORG_ID和SHIFTLEFT_ACCESS_TOKEN環境變量,以便CircleCI可以與ShiftLeft通信。您可以通過ShiftLeft儀表板獲取這些變量的值(單擊右上角的用戶圖標並單擊帳戶設置)。

步驟3:配置存儲庫

您將需要對存儲庫進行以下更改,您將在其中推動代碼更改:

1 啓用GitHub檢查CircleCI設置

2 設置分支保護規則。爲此,請導航到GitHub存儲庫。進入Settings > Branches ,在Branch protection rules區域,點擊Add rule

3 在Branch name pattern下輸入*,以確保該規則適用於所有分支

4 在“Branch name pattern”下,檢查Require status checks to pass before merging,並在此存儲庫標題的最後一週中找到的狀態檢查中選擇您希望需要的狀態檢查

5 滾動到頁面底部,然後單擊Create繼續

步驟4:調用ShiftLeft獲取結果

一旦Inspect分析了您的代碼,您就可以爲Inspect的分析結果調用ShiftLeft的Vulnerabilities API。ShiftLeft根據您的構建規則測試它的發現,構建規則用於測試漏洞類的存在,構建規則基於您創建的過濾器。實際上,您是在爲ShiftLeft提供您認爲可接受的實現參數。

您可以根據這些結果觸發特定的操作。例如,您可以選擇構建失敗、觸發電子郵件或Slack通知通知您的員工您的代碼中存在漏洞,或其中的一些組合。

步驟5:回顧你的結果

如果需要,您可以手動檢查檢查分析的結果。在其結果輸出中,Inspect將爲您提供一個URL,您可以使用該URL訪問ShiftLeft儀表板,該儀表板顯示找到的漏洞。

對於每個識別的漏洞,您可以設置其狀態,以指示需要做什麼(如果有的話)工作。ShiftLeft提供以下狀態值

參數 描述
Assign 表示該漏洞已被指定給負責方。儀表板還將顯示該人的姓名
Fixed 已識別的漏洞已修復;不需要進一步的工作
Ignore 識別的漏洞將被忽略

我們還建議使用您選擇的漏洞管理系統來跟蹤已經完成的關於已識別的漏洞的工作,以及需要完成的工作。對於標記爲忽略的項,您可以選擇修改您的ShiftLeft策略來忽略這些類型的漏洞。

How to Work with Build Rules in Your Code Repository

在應用程序的存儲庫中,可以包含一個名爲shiftleft的配置文件。包含構建規則的yml。ShiftLeft可以將其分析結果與構建規則進行比較,以確定構建是否應該失敗。

有了這個文件,您就可以:

爲每個應用程序/存儲庫指定不同的構建規則

將構建規則置於版本控制之下

編輯您的構建規則,而不需要開發工作流之外的單獨工具

The shiftleft.yml File:默認情況下,配置文件在存儲庫中的位置應該是./shiftleft.yml。該文件的格式應該如下所示

build_rules:
  - id: build-rule-identifier
    severity:
      - SEVERITY_MEDIUM_IMPACT
      - SEVERITY_HIGH_IMPACT
    type:
      - SQL Injection
      - Sensitive Data Leak
    owasp_category:
      - a1-injection
    threshold: 10
  - id: another-build-rule
    severity:
      - SEVERITY_LOW_IMPACT
    threshold: 100

您可以在文件中包含多個構建規則。

以下是您可以在構建規則中包含的參數列表。所有構建規則參數都是可選的。

參數 描述
id 規則的字符串標識符
severity 要篩選的嚴重級別。可接受的值:SEVERITY_LOW_IMPACT、SEVERITY_MEDIUM_IMPACT、SEVERITY_HIGH_IMPACT
severity 要篩選的漏洞類型
owasp_category 要過濾的OWASP漏洞類別
threshold 發現的導致構建失敗的漏洞的數量。缺省值爲0,因此任何識別出的漏洞都會導致構建失敗

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章