【Python】Banditを使用して,コードのセキュリティ上の問題を検知する
概要
今回はPythonのStatic Application Security Testing (SAST)を実施してくれるツールであるbanditを使用してみました.
banditを用いることで,Pythonのコード上に潜むセキュリティの問題を検知することが可能です.
またpre-commitで使用することもでき,コミット時などに簡単にチェックを行うこともできます.
banditとは
banditとは,PythonのStatic Application Security Testing (SAST)を実施してくれるツールで,
Pythonのコード上に潜むセキュリティの脆弱性などを検知してくれるます.
特に複雑な設定も必要なく,簡単にコードの検査ができ,扱いやすいのも特徴です.
使い方
まずbanditをインストールします.pipで簡単にインストールできます.
pip install bandit
インストール後は以下を実行するだけです.
bandit -r path/to/your/code
-r
は,--recursive
の略で,これをつけることで,ディレクトリに対して,再起的に実行することができます.
またその他のオプションとして,-f
でファイル形式を指定し,-o
でそのファイルの保存先をしているすることも可能です.
bandit -r -f json -o ./resullt.json .
使ってみる
以下のコード(sample.py
)に対して,banditを実行してみます.
import yaml class Sample(): def __init__(self, password: str, data_path: str): self.password = password assert isinstane(password, int) if password == "root": self.is_admin = True else: self.is_admin = False self.data = yaml.load(data_path)
結果
$ bandit sample.py [main] INFO profile include tests: None [main] INFO profile exclude tests: None [main] INFO cli include tests: None [main] INFO cli exclude tests: None [main] INFO running on Python 3.9.1 [node_visitor] INFO Unable to find qualified name for module: sample.py Run started:2021-12-31 05:42:17.592097 Test results: >> Issue: [B101:assert_used] Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Severity: Low Confidence: High Location: sample.py:7:8 More Info: https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html 6 self.password = password 7 assert isinstane(password, int) 8 9 if password == "root": -------------------------------------------------- >> Issue: [B105:hardcoded_password_string] Possible hardcoded password: 'root' Severity: Low Confidence: Medium Location: sample.py:9:23 More Info: https://bandit.readthedocs.io/en/latest/plugins/b105_hardcoded_password_string.html 8 9 if password == "root": 10 self.is_admin = True -------------------------------------------------- >> Issue: [B506:yaml_load] Use of unsafe yaml load. Allows instantiation of arbitrary objects. Consider yaml.safe_load(). Severity: Medium Confidence: High Location: sample.py:14:20 More Info: https://bandit.readthedocs.io/en/latest/plugins/b506_yaml_load.html 13 14 self.data = yaml.load(data_path) 15 -------------------------------------------------- Code scanned: Total lines of code: 10 Total lines skipped (#nosec): 0 Run metrics: Total issues (by severity): Undefined: 0.0 Low: 2.0 Medium: 1.0 High: 0.0 Total issues (by confidence): Undefined: 0.0 Low: 0.0 Medium: 1.0 High: 2.0 Files skipped (0):
こんな感じでコードのセキュリティ的な問題点を指摘してくれました.
assert
文を使うな,やパスワードのハードコードだけでなく,yaml.load
の脆弱性についても指摘してくれています.
pre-commitで使用する
最後にgitのフックスクリプトを簡単に管理できるpre-commitを使用して,コミット前にbanditによる検査を実施するようにしてみます.
pre-commitのより詳しい使い方に関しては,以下の記事を参照してください.
まず,pre-commitをインストールします.
pip install pre-commit
次にgit配下のレポジトリにて以下を実行します.
pre-commit install
.pre-commit-config.yaml
という名前のファイルを作成し,以下を記述します.
repos: - repo: https://github.com/PyCQA/bandit rev: 1.7.0 hooks: - id: bandit
先程のsample.py
をコミットしてみます.
$ git add . $ git commit -m 'test' [INFO] Initializing environment for https://github.com/PyCQA/bandit. [INFO] Installing environment for https://github.com/PyCQA/bandit. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... bandit...................................................................Failed - hook id: bandit - exit code: 1 [main] INFO profile include tests: None [main] INFO profile exclude tests: None [main] INFO cli include tests: None [main] INFO cli exclude tests: None [main] INFO running on Python 3.9.1 [node_visitor] INFO Unable to find qualified name for module: sample.py Run started:2021-12-31 06:01:41.575370 Test results: >> Issue: [B101:assert_used] Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Severity: Low Confidence: High Location: sample.py:7 More Info: https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html 6 self.password = password 7 assert isinstane(password, int) 8 9 if password == "root": (以下略)
コミット時にBanditを実行させて,コード上のセキュリティの問題を発見することができました!
その都度自分でbandit
コマンドを実行させる必要がなく,非常に便利そうです
まとめ
PythonのStatic Application Security Testing (SAST)を実施してくれるbanditを使用してみました.
またpre-commitと組み合わせることで,自動的にPythonのコード上に潜むセキュリティの問題を検知することも可能です.
非常に手軽なので,日頃の開発にも導入していきたいです.
参考
- PyCQA/bandit: Bandit is a tool designed to find common security issues in Python code.
- Pythonコードの安全を保つSAST(静的解析)ツール ~Bandit, Pyt~ - 好奇心の足跡
- pre-commit
- pre-commitでコミット時にコードの整形やチェックを行う