Python Table Manners - 安全性檢查

Category Tech

果然在沒有寫作松的督促下,馬上就拖稿了 XD
接下來要介紹在 Python 專案中做安全性檢查的工具

Safety - 檢查相依套件

depbot

不知道大家有沒有在 GitHub 上看過這樣的畫面
這個訊息告訴我們,專案的相依套件中可能有安全漏洞

透過 Safety 就能在本地做相依套件安全漏洞的檢查
它會到 safety-db 去查找已知的安全性漏洞
這個資料庫則是從 CVE (Common Vulnerabilities and Exposures) 整理出來的
如果是免費版,一個月會更新一次資料庫
付費版則可以達到即時更新

安裝

pipenv install safety --dev

執行

pipenv run safety check

safety-not-found

pycontw-postevent-report-generator commit 128d ,透過 safety 不會找到任何安全漏洞

如果想要測試 Safety 的功能可以安裝套件 insecure-package (這個套件是真的存在的,而且是不安全的,僅作為測試用途)

pipenv install insecure-package --dev

再試一次就能看到 Safety 將 insecure-package 列為不安全的套件

safety-found-insecure

另外需要注意的是 safety check 是對當前環境做檢查
務必確定已經有進入專案的虛擬環境,不然 Safety 只會檢查到本機使用的套件有沒有漏洞

如果想要對 requirements.txt 做檢查,則可以加上參數 -r

# 因為這個 case 不是針對 pipenv ,所以前面沒有加上 pipenv run
safety check -r requirements.txt

雖然 Safety 並不支援對 Pipfile 進行檢查 (Ref: Add Pipfile support #47),但 pipenv 就內建有安全性檢查的指令

pipenv check

bandit - 程式碼靜態分析

除了套件安全性的分析外,接著還能透過 bandit 來對自己的程式碼做靜態分析找出常見的漏洞

安裝

pipenv install bandit --dev

使用

pipenv run bandit -r <package>

bandit-result

執行後就會看到一個列表,整理出專案中可能有的安全性漏洞
每一個項目中會有以下五個欄位

  • Issue: 問題
  • Severity: 嚴重性
  • Confidence: 可信度
  • Location: 位置(在程式碼的哪一行)
  • More Info: 詳細的原因和可能的解決方案 (也可以從 Complete Test Plugin Listing 找到全部的列表)

加上參數 -i (可信度) 和 -l (嚴重性),就可以讓 bandit 只回報特定程度的漏洞
越多的 i / l 代表程度越高
以下指令就是讓 bandit 只回報高嚴重性 (-lll)、高可信度 (-iii)的漏洞

pipenv run bandit -iii -lll -r <package>

局部跳過檢查

有時候 bandit 給的警告不會在所有狀況都適用
B101: assert_used 為例
警告不該使用 assert
在使用 python -o 指令產生優化過的 byte code 時,會跳過 assert
如果系統使用 assert 來進行登入的檢查,就會讓使用者在完全沒驗證的情況下成功登入
但大部分的時候,我們不太會這麼實作
assert 也是在測試中很常使用到的語法

這時候就可以在專案的最上層加入設定檔 .bandit
而它的格式會長這樣

[bandit]
# 要執行 bandit 檢查的檔案或資料夾(逗號分隔)
targets:
# 跳過 bandit 檢查的檔案或資料夾(逗號分隔)
exclude:
# 要跳過的檢查種類 (逗號分隔)
skips:
# 要執行的檢查種類 (逗號分隔)
tests:

執行 bandit 時要加上 --ini .bandit 讓 bandit 知道要找這份設定檔

bandit --ini .bandit

如果不是整個檔案或種類要跳過,則可以在程式碼後面加上 # nosec

Reference