注意: 雖然 JavaScript 對於本網站不是必需的,但您與內容的互動將受到限制。請開啟 JavaScript 以獲得完整的體驗。

為您的 Python 應用程式提供整潔、安全的程式碼

引言

如今的開發人員肩負著巨大的責任——他們不僅要解決行業中一些最大的挑戰,而且從一開始就要以最高的程式碼質量和安全標準交付這些解決方案。

這裡重點介紹的成功案例說明了為什麼靜態程式碼分析工具在提升程式碼質量和程式碼安全的努力中至關重要,以及它們如何幫助 Python 社群在一些知名的開源 Python 專案中識別(並修復)缺陷和漏洞。

日益增長的技術債和安全擔憂

隨著 Python 應用程式在新的創新用例中迅速增長,開發團隊面臨著越來越大的壓力,他們需要滿足最後期限並按時交付專案——這往往導致程式碼的可靠性、可維護性和安全性被置於次要位置。這樣做不僅會累積長期的技術債,還可能在程式碼庫中留下巨大的安全漏洞。

為了在開發過程的早期(即“左移”方法)發現問題,團隊通常對新的、先進的工具感興趣,以評估它們是否能很好地融入其工作流程、是否足夠直觀,以及是否能幫助他們實現這一目標。值得慶幸的是,有許多工具和工作流程可以幫助 Python 使用者。事實上,Python 生態系統擁有豐富的 linting 和靜態分析工具(例如 PyLint、Flake8、Bandit、PyT、PySa 等等),大多數 Python 開發人員已經在使用其中的一種或多種。

在 SonarSource,我們對開發社群的需求(和痛點)瞭如指掌。事實上,我們相信只有開發人員才能對程式碼質量和程式碼安全產生可持續的影響。因此,我們構建了開源和商業程式碼分析器——SonarLint、SonarCloud、SonarQube,其使命是幫助團隊在現有工作流程中解決編碼問題。在這一使命中,我們也承擔著巨大的責任,這意味著提供精確且可操作的反饋,並以高精度(即最小化誤報)發現問題。

在下一節中,我們將討論分析流行的開源 Python 專案不僅是為貢獻者提供寶貴反饋的機會,也是持續提高靜態程式碼分析工具質量和精度的機會——這是一個由社群驅動的協作迴圈。

在流行的 Python 專案中發現的缺陷和漏洞

我們使用 SonarCloud 分析了 tensorflow、numpy、salt、sentry 和 biopython 等幾個開源專案,以識別任何明顯的漏洞。我們知道,這些高知名度的開源專案通常被成千上萬的專案使用,並且它們的開發工作流程包含了所有最佳實踐——程式碼審查、測試覆蓋、使用多種工具(flake8、pylint、Bandit…)。我們使用 SonarCloud 分析了這些專案,結果非常有趣。毫無疑問,這些問題很快得到了這些專案的確認和修復。

“[SonarCloud] 發現的某些問題令人印象深刻(可能是透過某種內省和/或型別推斷驅動的),而不僅僅是我在大多數 flake8 生態系統中習慣的簡單模式匹配。”

--- Peter J. A. Cock - BioPython 維護者 (原始帖子在此)

下面重點介紹了一些被分析專案的例子,以及被其他工具忽略但被 SonarCloud 標記出的問題。在閱讀這些例子時,不僅可以思考工具的能力,還可以將其視為一個學習機會,以便在未來主動避免類似的陷阱。

型別錯誤

下面的例子展示了在 Tensorflow 上發現的問題——一個由 Google 開發的用於機器學習的開源平臺。

SonarCloud 擁有一個型別推斷引擎,使其能夠檢測高階的型別錯誤。它利用能找到的每一點資訊來推斷變數型別,包括 Typeshed 存根、賦值和您的型別註解。同時,即使您不使用型別註解,它也不會報錯,並且其設計旨在避免誤報。

在這裡,控制流分析使其能夠理解 `state_shape` 是一個元組,因為它在 `output_shape` 是一個 `tuple` 時被賦值為 `output_shape[1:]`。該演算法能夠忽略後來對 `output_shape` 的 `list` 賦值。

無法訪問的程式碼

下面的例子展示了在 Sentry 上發現的問題——一個用於監控 Python 效能和錯誤瓶頸的庫。

當死程式碼緊跟在 `return` 或 `raise` 語句之後時,檢測起來很容易。但當 `return` 是有條件的,情況就變得複雜一些。SonarCloud 使用控制流圖來檢測多個分支在到達某條語句之前就已退出的情況。

格式化字串中的欄位錯誤

下面的例子展示了在 Salt Project 上發現的問題——一個用於事件驅動自動化、遠端任務執行和配置管理的 Python 包。

在字串格式化過程中,引用錯誤的欄位名或索引是相當常見的。Pylint 和 Flake8 有規則可以檢測字串字面量中的這個問題,但當格式字串位於變數中時,它們會漏掉這些缺陷。

未丟擲的異常

下面的例子展示了在 Biopython 上發現的問題——一個用於生物計算和資訊學的工具。

當我們審查程式碼時,通常會關注類、變數和其他有意義的符號,而常常忘記檢查一些小細節,例如“我的異常前面是否有 raise 關鍵字”。SonarCloud 會分析整個專案以提取型別層次結構。它能檢測到自定義異常被丟棄的情況,而不僅僅是內建異常。

無意義的比較

下面的例子展示了在 Numpy 上發現的問題——一個用於處理大型多維陣列和矩陣的數值計算庫。SonarCloud 有許多規則可以檢測沒有意義的程式碼。用 `==` 比較不相容的型別永遠不會失敗,但它總是返回 False,如果使用 `!=` 則返回 True。在這裡我們可以看到一個問題,因為 `platform.architecture()` 返回的是一個元組。


這些只是幾個例子,您可以在各個 GitHub 專案上找到所有被專案維護者標記和修復的問題 – tensorflownumpysaltsentrybiopython

在正確的時間和地點提供正確的指導

構建和維護優秀的軟體涉及多個團隊使用多種工具,因此,為團隊提供能夠在正確的時間和地點提供正確指導的工具至關重要。

SonarLintSonarQubeSonarCloud 可以透過以下方式幫助 Python 開發人員更好地完成工作:

  • 從 IDE 開始,貫穿程式碼審查工作流程,直至部署流水線,實現自動化程式碼分析。
  • 在開發週期的早期檢測各種程式碼質量和程式碼安全問題。
  • 幫助團隊實現“編碼即淨化(Clean as you Code)”,從而使交付的新程式碼達到最高的質量和安全標準,並因此減少長期技術債。

要在您的 IDE 中邊寫程式碼邊快速檢測問題,可以從您選擇的 IDE 市場下載 SonarLint(開源且完全免費):www.sonarlint.org/

SonarQube 和 SonarCloud 分別是本地部署和雲端解決方案,它們幫助專案在程式碼倉庫平臺(如 GitLab、GitHub、Azure DevOps 或 Bitbucket)中檢測缺陷、漏洞、程式碼異味和安全熱點,使團隊只合並高質量和安全的程式碼。它們對任何開源專案都是完全免費的。您可以在 www.sonarqube.comwww.sonarcloud.com 上試用。

如果您好奇您的 Python 程式碼倉庫中可能隱藏著哪些缺陷或漏洞,那麼就像我們在前面的例子中所做的那樣,去分析您的專案吧。這是加強您的開發流程並在早期發現問題的絕佳機會。在這個過程中,您可能還會發現這是一個很好的學習機會,並瞭解到一些您可能不知道的最佳實踐和/或危險模式。