秘密を含む接続文字列は、組み立てる前に構成要素を検証する — パーサのエラー型が raw 入力を文字列化してログへ残す
セキュリティ
バリデーション
ロギング
知識
判断
パスワードを含む URL 形式の接続文字列(DB の DSN 等)を組み立てるとき、構成要素を無検証で埋めるとパーサのエラーメッセージ経由で資格情報がログへ残る。「DSN をログに出さない」という契約をコードに書いていても、同じ関数の中で破られる。
機序
一般的な URL パーサは、入力に制御文字(改行等)が含まれるとパースを拒否し、そのエラー型に元の入力文字列を保持する。エラーの文字列表現はその raw 入力を含むため、パスワードごと出力される。さらにドライバによってはこの失敗を戻り値ではなく panic で返すため、スタックトレースとともに標準エラーへ出て、コンテナログに永続化される。
発火点は特殊な攻撃ではなく、管理画面の環境変数欄へ値を貼るときの末尾改行のような日常的な事故でよい。
判断基準
- 「エラーログに DSN を出さない」だけでは不十分。自分が書いたログ出力だけを見ていると、ライブラリが同じ情報を別経路で出す
- operator が自由文字列を与えられる構成要素(ホスト名・TLS モード・オプション等)を設定化するときは、受け付ける値の集合を列挙して検証する。集合が小さい項目なら完全列挙ができる
- 検証の位置は設定読み込み層。接続文字列を組む直前ではなく、値がプロセスに入った直後に弾く。設定読み込み関数がエラーを返すシグネチャを持ちながら常に nil を返しているなら、そこが最初の実用途になる
- 副次効果として、設定ミスが panic ではなく読めるメッセージになる
確認方法
制御文字を含む値・大文字違い・typo・前後の空白を入力にしたテストを置き、設定読み込みがエラーを返すことを固定する。同時に、受け付けるべき値を全部通すテストも置く(検証が厳しすぎて正当な設定を拒む退行を防ぐ)。