在生產環境中發現的軟體漏洞,其修復成本平均是開發過程中發現漏洞的四倍。 IBM 發布的《2025 年資料外洩成本報告》指出,平均每次資料外洩的成本高達 4.88 萬美元。而源自於未被發現的原始碼漏洞的資料洩露,修復成本更是高昂,因為其根本原因不僅需要事件回應,還需要對程式碼庫進行修復。程式碼掃描工具的存在,正是為了儘早發現漏洞,將其引入開發環境,而不是等到資料外洩發生之後。
程式碼掃描是對原始程式碼、已編譯二進位檔案或正在運行的應用程式進行自動化分析,旨在軟體投入生產環境之前識別安全漏洞、品質缺陷、違規行為和技術債。它是應用程式安全的基礎層,並非滲透測試或威脅建模的替代品,而是系統性的基準,能夠捕捉那些人工審核人員難以大規模持續發現的、可預測的、可重複出現的錯誤類型。
什麼是條碼掃描?
程式碼掃描是對軟體工件(原始碼、字節碼、二進位檔案或正在運行的應用程式)進行自動化檢查,以識別缺陷,而無需人工逐行審查。掃描工具應用規則集、模式匹配、資料流分析,以及在更高級的工具中應用過程間污點跟踪,來發現那些原本會在生產環境中未被發現的問題。
程式碼掃描並非程式碼審查、架構分析、滲透測試或執行時間監控的替代品。它是一種快速、系統化、可擴展的初步篩選機制,能夠可靠且一致地捕獲整個程式碼庫中的已知模式,包括那些程式碼審查人員由於其看似常規而忽略的部分。
在此語境下,程式碼驗證的意思是:程式碼驗證確認程式碼的行為符合其規範。掃描是驗證的一個組成部分,它是處理模式檢測和資料流分析的自動化組件。人工審查、測試和形式驗證是其他組成部分。它們共同構成了一個驗證程序;僅靠掃描是不夠的。
靜態程式碼掃描與動態程式碼掃描:核心區別
在建立掃描程式時,最重要的選擇是了解每種方法何時運行以及它可以看到什麼:
| 尺寸 | 靜態(SAST) | 動態(DAST) |
|---|---|---|
| 當它運行時 | 原始碼無需執行 | 針對正在運行的應用程式 |
| 它所看到的 | 程式碼結構、資料流、模式違規 | 運行時行為、伺服器配置、API回應 |
| 發現 | SQL注入漏洞、硬編碼金鑰、不安全的加密技術、程式碼異味 | 身份驗證繞過、運行時注入、會話管理缺陷、伺服器配置錯誤 |
| 未命中 | 僅運行時漏洞、配置問題 | 測試期間未觸發程式碼級模式 |
| 速度 | 速度快,只需幾秒鐘到幾分鐘即可完成。 | 速度慢,需要運作環境 |
| 開發者回饋 | 立即提交、IDE提交或預先提交 | 延遲,需要部署應用程式 |
| 誤報率 | 較高,缺乏運行時上下文 | 降低,證實了可利用性 |
| 最佳集成 | IDE、預先提交、每次 PR 都使用 CI/CD | 預發布環境,預發布門 |
對大多數團隊來說,切實可行的方案是:兩者都運作。在 IDE 和 CI 管線中進行靜態掃描可以快速且及時地回饋程式碼模式。針對預發布環境的動態掃描可以確認漏洞的可利用性,並發現靜態分析無法偵測到的設定問題。
四種條碼掃描類型
靜態應用程式安全測試 (SAST)
SAST(靜態應用安全測試)無需執行程式碼即可分析原始程式碼、字節碼或二進位。它是最常見的程式碼掃描方式,已整合到整合開發環境 (IDE) 和持續整合/持續交付 (CI/CD) 管線中。 SAST 透過污點分析(追蹤不受信任的輸入到危險的接收器)發現注入漏洞,透過模式匹配發現加密濫用漏洞,透過字串分析發現硬編碼憑證漏洞,並透過指標和模式規則發現結構品質問題。
最佳工具: Semgrep、SonarQube、Checkmarx、CodeQL、Veracode、Snyk Code SMART TS XL.
DAST,動態應用程式安全測試
DAST 針對即時應用程式運行,發送精心建構的輸入並觀察回應。它無法查看原始程式碼,而是像攻擊者一樣從外部與應用程式互動。 DAST 可以發現 SAST 無法偵測到的身份驗證繞過、業務邏輯缺陷、伺服器端請求偽造和設定漏洞,因為這些漏洞需要執行時間情境。
最佳工具: OWASP ZAP、Burp Suite、Invicti、Acunetix、HCL AppScan。
軟體成分分析 (SCA)
SCA掃描依賴清單(package.json, pom.xml, requirements.txt, go.mod)針對漏洞資料庫,識別第三方庫中已知的 CVE。幾乎所有現代應用程式都使用開源依賴項。 SCA 掃描層確保這些依賴項不會引入已知漏洞。
最佳工具: Snyk、OWASP Dependency-Check、Mend(原名 WhiteSource)、GitHub Dependabot、npm audit。
IAST,互動式應用程式安全測試
IAST 使用嵌入在應用程式伺服器中的代理程式或感測器在執行時對應用程式進行偵測。它從應用內部觀察實際的請求處理過程,結合了 DAST 的運行時準確性和 SAST 的程式碼級洞察力。 IAST 的誤報率在四種類型中最低,但需要已進行偵測的部署環境。
最佳工具: Contrast Security、Seeker(Synopsys)、HCL IAST。
如何結合使用它們:每次提交都運行 SAST,以便快速獲得開發人員回饋。每次依賴項變更都執行 SCA。每次發布前對預發布環境運行 DAST。對於必須最大限度降低誤報率的關鍵應用程序,請添加 IAST。
程式碼掃描究竟能發現什麼
不同的掃描類型可以捕捉不同的漏洞類別。這種映射關係有助於團隊了解針對其特定風險狀況應該投資哪種掃描器:
| 漏洞類別 | SAST | 達斯特 | SCA | 國際航空運輸協會 |
|---|---|---|---|---|
| SQL注入 | 強(污染分析) | 強(積極測試) | 沒有 | 強大 |
| XSS | 中度 | 強大 | 沒有 | 強大 |
| 硬編碼的密鑰/憑證 | 強(模式匹配) | 沒有 | 局部的 | 沒有 |
| 身份驗證失敗 | 部分(僅圖案) | 強大 | 沒有 | 強大 |
| 易受攻擊的依賴項(CVE) | 沒有 | 沒有 | 強大 | 沒有 |
| 密碼學濫用 | 強(已知不良 API) | 沒有 | 局部的 | 局部的 |
| 安全配置錯誤 | 部分(程式碼中的配置) | 強大 | 沒有 | 局部的 |
| SSRF | 強(污染分析) | 強大 | 沒有 | 強大 |
| 路徑遍歷 | 強大 | 中度 | 沒有 | 強大 |
| 命令注入 | 強(污染分析) | 強大 | 沒有 | 強大 |
| 代碼品質/技術債務 | 強大 | 沒有 | 沒有 | 沒有 |
| 死程式碼 | 強大 | 沒有 | 沒有 | 沒有 |
軟體開發生命週期中的程式碼掃描:何時執行什麼
安全領域的「左移」原則,即盡可能在開發生命週期的早期階段進行漏洞檢測,正是程式碼掃描成為標準實務的原因。在開發人員的整合開發環境 (IDE) 中發現 SQL 注入漏洞只需幾分鐘即可修復。而在發生安全漏洞後,在生產環境中發現此類漏洞則需要數週時間進行事件回應、補救和監管報告。
在整合開發環境 (IDE) 中: SonarLint、Snyk IDE 擴充和 Semgrep IDE 外掛程式會在開發者編寫程式碼時直接顯示漏洞資訊。當有漏洞的程式碼行被寫入時,SQL 注入警告標誌就會出現,修復起來只需幾秒鐘。
提交前鉤子:在代碼提交到代碼倉庫之前運行快速的SAST規則和密鑰檢測。提交前鉤子應該速度很快,最好在十秒以內,否則開發者會停用它們。
每個拉取請求都會進行完整的 SAST 掃描和 SCA 檢查。大多數團隊都會在此環節嚴格把控質量,一旦發現新的嚴重問題,就會阻止合併。
每日或每週:深度過程間分析、完整的 DAST 掃描、全面的 SCA 審計。這些操作對於每次提交都執行來說速度太慢,但會在主分支上定期運行。
完整的 CI/CD 掃描配置:
雅姆
# GitHub Actions: layered scanning at the right pipeline stage
name: Code Scanning Pipeline
on:
push:
branches: [main, develop]
pull_request:
jobs:
sast:
name: Static Analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep SAST scan
uses: semgrep/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/security-audit
p/secrets
- name: SonarCloud quality gate
uses: SonarSource/sonarcloud-github-action@master
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
sca:
name: Dependency Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Snyk dependency check
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high
secrets:
name: Secret Detection
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: TruffleHog secret scan
uses: trufflesecurity/trufflehog@main
with:
extra_args: --only-verified
條碼掃描工具:實用概述
| 工具 | 類型 | 最適合 | 開源 |
|---|---|---|---|
| 塞姆格雷普 | SAST | 自訂規則、快速掃描、多語言 | 是的(社區規則) |
| SonarQube / SonarCloud | SAST | 品質+安全、CI/CD整合、趨勢追蹤 | 社群版 |
| 代碼QL | SAST | 深度語意分析,GitHub原生 | 可以 |
| 校驗碼 | SAST | 企業應用安全計畫、合規性 | 沒有 |
| Snyk 程式碼 | SAST | 對開發者友善、IDE優先的安全機制 | 免費增值模式 |
| OWASP ZAP | 達斯特 | 免費DAST,相容於CI/CD | 可以 |
| Burp套房 | 達斯特 | 手動+自動化網頁應用程式安全測試 | 社群版 |
| Snyk / Mend | SCA | 依賴性漏洞管理 | 免費增值模式 |
| OWASP Dependency-Check | SCA | 開源依賴項 CVE 掃描 | 可以 |
| 對比安全 | 國際航空運輸協會 | 運行時準確率高,誤報率低 | 沒有 |
| SMART TS XL | SAST + 結構 | 多語言、COBOL、企業級、傳統系統 | 沒有 |
有效代碼掃描的最佳實踐
首先,使用高置信度、低雜訊的規則。如果第一天就運行所有可用的規則集,會產生成千上萬條結果,讓開發人員不堪重負,最終阻礙工具的普及。建議先從精心挑選的高風險、高置信度規則集入手,例如 OWASP Top 10 模式、秘密檢測規則以及已知的危險函數呼叫。隨著團隊對工具的信心增強,再逐步加入規則。
僅對新程式碼強制執行。對於已有安全性問題的遺留程式碼庫,配置品質門控,使其僅阻止當前 PR 中引入的安全問題(而非整個程式碼庫),即可將安全檢查融入工作流程,而不會造成預先存在的安全問題積壓,從而阻礙所有開發工作。
雅姆
# SonarQube: new-code quality gate configuration
# Block merges on new critical security hotspots only
sonar.qualitygate.wait=true
sonar.newCode.referenceBranch=main
# Existing findings in main don't block PRs
# Only new findings in the PR diff are gated
系統性地調整誤報。開發人員調查一次後便忽略的誤報只是令人煩惱,但如果連續六個月每次 PR 都觸發誤報,就會讓開發人員養成完全忽略誤報的習慣。建立一套審查流程:每次誤報都需要有書面說明,並且每季進行一次審查。
將調查結果與嚴重程度等級對應。並非所有調查結果都需要立即採取行動。分級回應:
- 危急 (CVSS 9+,已確認可利用):阻止部署,24小時內修復
- 高 (CVSS 7-8):阻止 PR 合併,在迭代周期內修復
- 媒材新增到待辦事項清單,季度內解決
- 低/資訊量:追蹤、處理重構過程中的問題
衡量真正重要的指標。以嚴重程度追蹤平均修復時間 (MTTR)、每個迭代周期中已解決問題與已發現問題的比率,以及一段時間內的誤報率。這些指標可以告訴你掃描程式是否有效,而不僅僅是掃描程式是否在運作。
程式碼掃描如何預防技術債
技術債的累積源自於品質問題的延遲,例如,原本可以在開發階段透過SAST規則捕捉的SQL注入漏洞,最終卻進入生產環境,需要透過安全性修補程式、回歸測試和部署協調等方式進行修復。程式碼掃描工具能夠從源頭攔截這種技術債的累積。
三種機制將程式碼掃描與技術債減少直接連結:
複雜度檢測。圈複雜度超過閾值、嵌套過深的條件語句以及冗長的函數都是程式碼異味,掃描工具會將其標記出來。如果不加以解決,這些模式會不斷累積,導致程式碼庫越來越難修改,成本也越來越高。掃描工具提供基於指標的早期預警,促使我們在複雜度演變為結構性問題之前進行重構。
重複代碼檢測。重複程式碼是技術債中最昂貴的形式之一,每次錯誤修復和功能變更都必須在多個地方應用,而副本之間不可避免地會出現差異。 SonarQube 的重複程式碼偵測和類似規則可以識別程式碼庫中的這種模式,從而在差異導致不一致之前進行合併。
死代碼識別。死程式碼是指那些從未被任何生產環境執行路徑呼叫的函數和模組,它們會增加程式碼庫的大小,使開發人員感到困惑,並使遷移分析變得複雜。執行可達性分析的掃描工具可以系統地識別死代碼,從而在死代碼進一步累積之前將其移除。
綜合效應:持續掃描的程式碼庫比起未進行掃描的同類程式碼庫,缺陷密度更低、圈複雜度更低、重複程式碼率更低、死程式碼比例也更低。這些指標直接轉化為更快的功能開發速度、更低的維護成本和更低的生產事故風險。
SMART TS XL 提供企業級代碼掃描
標準代碼掃描工具通常在單一語言環境下運作。但在企業環境中,Java 服務、Python 管道、COBOL 批次程式、JCL 作業流程和 RPG 模組等多種語言並存,每種語言都需要獨立的掃描器、獨立的配置和獨立的掃描結果儀錶盤,導致程式碼掃描呈現碎片化狀態。
SMART TS XL“ 靜態程式碼分析 它可同時掃描環境中所有語言,包括 COBOL、JCL、Java、Python、RPG、PL/I、SQL 和現代技術棧,並在一次分析中產生涵蓋整個產品組合的統一品質指標、安全性發現和結構化資料。對於同時擁有傳統大型主機應用程式和現代雲端服務的組織而言,這種跨語言覆蓋範圍決定了掃描程式是否僅涵蓋現代技術堆疊還是覆蓋整個系統。
應用程式依賴關係映射功能將掃描範圍從單一檔案擴展到架構分析:哪些元件耦合度最高,哪些地方存在循環依賴,哪些程式透過隱式檔案介面而非明確 API 共享資料。這些結構性發現正是單一檔案模式匹配工具無法偵測到的架構安全性和品質問題。
影響分析功能使掃描結果能夠大規模地轉化為可操作的措施:當在一個被 150 個程式依賴的高扇入元件中發現漏洞時,影響分析會確定修復工作的範圍,包括需要測試的程式、需要更新的呼叫者以及修復程式的影響範圍。這使得漏洞發現不再只是一系列問題,而是轉化為一個具有明確範圍的結構化修復方案。
企業搜尋功能可讓掃描結果在整個產品組合中進行查詢:在幾秒鐘內,尋找使用特定不安全 API 的每個程式、包含硬編碼憑證的每個檔案、超過複雜度閾值的每個元件,涵蓋數百萬行程式碼,支援任何語言組合。
對於管理團隊 遺產現代化 程式, SMART TS XL的掃描提供了遷移前的品質基準:從遷移範圍中排除的死代碼、決定遷移順序的複雜性分佈,以及在將轉換後的程式碼部署到雲端基礎設施之前必須修復的安全性問題。
儘早掃描,持續掃描,掃描所有內容
修復安全漏洞平均時間最短的組織,並非那些擁有最激進的滲透測試方案的組織。它們往往是在漏洞進入程式碼審查階段之前,在開發人員的整合開發環境(IDE)、提交前鉤子以及持續整合/持續交付(CI/CD)管線中,就發現了最多的漏洞。程式碼掃描正是實現大規模漏洞修復的關鍵。
建立掃描程序意味著根據風險狀況選擇合適的SAST、DAST、SCA和IAST組合,在開發生命週期的適當節點整合這些組合,進行調整以在不犧牲覆蓋範圍的前提下最大限度地減少噪聲,並持續衡量程序的有效性,而不是僅僅假設掃描程序正在運行。掃描程式運作只是開始,程式有效運作才是最終目標。