IDS06-J. 無害化されていないユーザ入力を使って書式指定文字列を組み立てない
java.ioパッケージに含まれるPrintStreamクラスには、format()とprintf()という2つの等価な書式組み立てメソッドがある。System.outとSystem.errはPrintStreamオブジェクトなので、PrintStreamのメソッドは標準出力と標準エラー出力に対して呼び出すことができる。これらのメソッドを使うことのリスクは、CやC++の似た関数を使うことほど高くない[Seacord 2013]。標準ライブラリ実装は、引数が対応する書式指定子に一致しない場合、例外をスローする。例外のスローは攻撃の軽減に役立つものの、信頼できないデータが書式指定文字列に組み込まれると、情報漏えいやサービス運用妨害を許す結果になりかねない。それゆえ、信頼できない入力源からの無害化されていない入力値を使って書式文字列を組み立ててはならない。
違反コード
以下の違反コードでは、ユーザのクレジットカード情報が漏えいする。信頼できないデータを書式指定文字列の組み立てに使っている。
class Format {
  static Calendar c = new GregorianCalendar(1995, GregorianCalendar.MAY, 23);
  public static void main(String[] args) {  
    // args[0]はクレジットカードの有効期限を含むはずだが
    // %1$tmや%1$te、%1$tYといった書式指定子が含まれるかもしれない
    System.out.format(
      args[0] + " did not match! HINT: It was issued on %1$terd of some month", c
    );
  }
}
適切な入力値検査を行っていないため、攻撃者は%1$tmや%1$te、%1$tYのような書式指定子を含む入力をプログラムに与えることで、入力の確認対象となる日付を取得できる。上記の例では、これらの書式指定子はそれぞれ「05 (May)」「23 (day)」「1995 (year)」と出力する。
適合コード
以下の適合コードでは、信頼できないユーザ入力を書式指定文字列から除外している。arg[0]が書式指定子を含む可能性は残っているものの、不活性化されている。
class Format {
  static Calendar c = 
    new GregorianCalendar(1995, GregorianCalendar.MAY, 23);
  public static void main(String[] args) {  
    // args[0]はクレジットカードの有効期限を指す
    // cと比較し、一致しない場合に以下の行を出力する
    System.out.format(
      "%s did not match! HINT: It was issued on %terd of some month", 
      args[0], c
    );
  }
}
リスク評価
信頼できないデータを使って書式指定文字列を組み立てると、情報漏えいやサービス運用妨害につながる可能性がある。
| 
         ルール  | 
      
         深刻度  | 
      
         可能性  | 
      
         修正コスト  | 
      
         優先度  | 
      
         レベル  | 
    
|---|---|---|---|---|---|
| 
         IDS06-J  | 
      
         中  | 
      
         低  | 
      
         中  | 
      
         P4  | 
      
         L3  | 
    
自動検出
静的解析ツールの汚染解析は、このルールへの違反のいくつかを検出できるだろう。
| ツール | バージョン | チェッカー | 説明 | 
|---|---|---|---|
| The Checker Framework | 
         2.1.3  | 
      Tainting Checker | Trust and security errors (see Chapter 8) | 
| Parasoft Jtest | 
         2024.1 
       | 
      CERT.IDS06.VAFS | Ensure the correct number of arguments for varargs methods with format strings | 
| Klocwork | 
         2024.3  | 
      SV.EXEC SV.EXEC.DIR SV.EXEC.ENV SV.EXEC.LOCAL SV.EXEC.PATH  | 
      Implemented | 
関連ガイドライン
| SEI CERT Perl Coding Standard | IDS30-PL. Exclude user input from format strings | 
| 
         ISO/IEC TR 24772:2013  | 
      
         Injection [RST]  | 
    
| 
         CWE-134, Uncontrolled Format String  | 
    
参考文献
| 
         [API 2006]  | 
      |
| 
         [Seacord 2013]  | 
      
         Chapter 6, "Formatted Output"  | 
    
| [Seacord 2015] | 
翻訳元
これは以下のページを翻訳したものです。
IDS06-J. Exclude unsanitized user input from format strings (revision 122)
