独自コードの信頼境界
独自の Python、Bash、PHP、Go、JavaScript、Java のコードを調べるときは、危険な関数名を探すだけで終わらせない。入力元から高権限処理が触るリソースまで、データの流れを追う。
低権限ユーザーの入力が、検証、保存、IPC、root 権限での処理のどこで信頼されるかを見る。shell=True、pickle、yaml.load、シンボリックリンク、shutil.move、アーカイブ展開、相対パスは、入力の制御者と実行 UID を確かめてから評価する。
データフローの確認
Section titled “データフローの確認”入力元 ↓変換・検証処理 ↓保存先または IPC ↓権限付きプロセス ↓危険な処理 ↓影響を受けるリソース見る入力元:
- コマンドライン引数
- 標準入力
- 環境変数
- 設定ファイル
- ログファイル
- 一時ファイル
- アップロードファイル
- アーカイブの中身
- Unix socket
- ファイルディスクリプタ
確認する処理:
subprocess.run(...)subprocess.Popen(...)os.system(...)os.execve(...)open(...)os.open(...)os.pread(...)shutil.copy(...)shutil.move(...)tarfile.extract(...)tarfile.extractall(...)zipfile.extract(...)zipfile.extractall(...)pickle.load(...)yaml.load(...)eval(...)exec(...)tempfile.*これらの呼び出しがあるだけでは脆弱とは断定しない。次を確認する。
- 引数を誰が制御できるか。
shell=Trueか。- パスが絶対か相対か。
PATHを信用しているか。- ファイルの owner、mode、ACL。
- 親ディレクトリを書き換えられるか。
- symlink を追従するか。
- 検証後に同じ inode またはファイルディスクリプタを使っているか。
- 実行 UID/GID。
- 呼び出し元と呼び出し先の権限差。
- エラー時に制限を解除する処理になっていないか。
エラー応答は副作用の不成立を示さない。TypeError や 502 のあとでも、callback、生成ファイル、ログを確認する。
説明テンプレート
Section titled “説明テンプレート”成立条件:攻撃者が制御するもの:信頼境界:問題のある処理:影響:なぜ成立するか:修正案:検知・ログ:未確認:修正案は、実際の処理に合うものだけを書く。
- shell を使わず、argv の配列で実行する。
- allowlist で service 名や action 名を制限する。
- 低権限ユーザーが書けるディレクトリを、root 権限で読み込むモジュールやチェックポイントの置き場にしない。
- 安全な一時ファイルを使う。
O_NOFOLLOW、owner と inode の再確認、FD ベースの処理で symlink と TOCTOU を避ける。- アーカイブの展開時にパストラバーサルを防ぐ。
- pickle や
torch.load相当を、信頼境界の外から来たファイルに使わない。 - systemd の hardening、最小権限、読み書きディレクトリの分離を行う。
検知に残るものはログと検知で見る。
データフローの例
Section titled “データフローの例”印刷ジョブの制御ファイル:
control file の J 行 ↓job_name ↓subprocess.Popen(..., shell=True) ↓/bin/sh ↓印刷サービスの shellFD の受け渡しはUnix socket とファイルディスクリプタに図を置いた。
管理 UI のサービス名:
service パラメータ ↓denylist の正規表現 ↓subprocess.run("systemctl status ...", shell=True) ↓サービス権限で symlink を作成 ↓sudo の root log viewer ↓2段 symlink 経由の root file readsudo された Python の plugin:
低権限ユーザーが書ける plugin directory ↓.pth ファイル ↓root sudo の site.addsitedir() ↓.pth ファイル内の import 行を実行 ↓root 所有の SUID bash学習ジョブの checkpoint:
処理済み入力が検証を通過 ↓DataLoader ↓共有ディレクトリ上の最新 .pt ↓CheckpointLoader / torch.load ↓pickle deserialization ↓root でのコマンド実行
