応用編:セキュリティとシェルスクリプトのベストプラクティス
静的解析ツール ShellCheck による事前検証、コマンドインジェクションの防止、安全な一時ファイルの生成、および保守性を高めるコーディング規約を解説します。
ShellCheck による静的コード解析
ShellCheck は、シェルスクリプトのバグ、セキュリティ脆弱性、およびスタイル違反を検出する業界標準の静的解析ツールです。
CI/CD パイプラインやコミット前フックに ShellCheck を組み込むことで、レビュー工数を削減し致命的な事故を未然に防ぎます。
# スクリプトの検証を実行
shellcheck deploy.sh
ShellCheck は以下のような典型的な問題を的確に指摘します。
- 変数のクォート漏れによる単語分割リスク(SC2086)
[[ ... ]]ではなく古い[ ... ]を使った比較ミス- 未定義の変数の参照やシバンの不整合
» 特定行での警告抑制
正当な理由で警告を無視したい場合は、直前の行にディレクティブを記述します。
# shellcheck disable=SC2086
cat $file_list
コマンドインジェクションの防止
外部からの入力値(引数、Web リクエスト、ファイル名等)をシェル内で扱う際は、コードとして解釈されないよう厳格に対処します。
» eval コマンドの完全な禁止
文字列をシェルコードとして実行する eval は、悪意あるコマンド(例: ; rm -rf /)を埋め込まれる危険が極めて高いため、使用してはなりません。配列やパラメータ展開で代替します。
» 入力値の厳格な検証
引数を処理する前に、想定された文字種(英数字のみ等)であることを正規表現で検証します。
USER_ID="$1"
if [[ ! "$USER_ID" =~ ^[a-zA-Z0-9_-]+$ ]]; then
echo "Error: Invalid user ID format." >&2
exit 1
fi
» 機密情報の平文露出防止
スクリプト内でパスワードを入力させる際は、画面に入力文字を表示させない -s オプションを使用します。
read -r -s -p "Enter password: " USER_PASS
echo
一時ファイルの安全な作成(mktemp)
/tmp/my_temp.txt のように固定のファイル名を使用すると、他ユーザーからの推測によるシンボリックリンク攻撃(悪意あるファイルの上書き)の標的になります。
一時ファイルやディレクトリは、必ず mktemp コマンドでランダムな名前を生成します。
# ランダムな一時ファイル(パーミッション 600 で作成される)
TEMP_FILE=$(mktemp)
# ランダムな一時ディレクトリ(パーミッション 700 で作成される)
TEMP_DIR=$(mktemp -d)
コーディング規約と可読性の向上
チーム開発や長期保守に耐えるスクリプトを書くための基本方針です。
» 1. コマンドの存在確認には command -v を使用する
外部ツールがインストールされているか確認する際、環境依存の強い which は避け、POSIX 準拠で組み込みの command -v を使用します。
if ! command -v jq > /dev/null 2>&1; then
echo "Error: 'jq' command is required but not installed." >&2
exit 1
fi
» 2. 変数の命名規則
- 環境変数・定数: 大文字スネークケース(例:
DATABASE_URL、MAX_RETRIES) - ローカル変数・ループ変数: 小文字スネークケース(例:
local file_name、for item in ...)
命名を明確に分けることで、システムの環境変数を誤って上書きするリスクを低減できます。