FIO05-J. wrap() や duplicate() メソッドで作成したバッファを信頼できないコードにアクセスさせない
IntBuffer、CharBuffer、ByteBuffer など java.nio パッケージのバッファクラスは、プリミティブデータ型の配列をバッファにラップし Buffer オブジェクトとして返す様々な wrap() メソッドを定義している。これらのメソッドは新しい Buffer オブジェクトを構築するが、構築された Buffer オブジェクトは入力として与えられた配列をそのまま使っている。これらのメソッドについて、Java API [API 2014] には以下のように記述されている。
新しいバッファは指定された
char配列を使ってつくられている。つまり、バッファに変更を加えると配列も変更され、配列に変更を加えるとバッファも変更される。
これらのバッファが信頼できないコードにアクセスされると、バッファで使われている配列が変更される可能性がある。同様に、duplicate() メソッド、array() メソッド、slice() メソッド、subsequence() メソッドが作成するバッファにも、元のバッファと同じ配列が使われる。このように複製したバッファへのアクセスを許すと、元の配列の不正な変更が行われる可能性がある。
違反コード (wrap())
以下の違反コード例では、char 型配列を宣言し、この配列をラップする CharBuffer を getBufferCopy() メソッドを通じて信頼できないコードに晒している。
final class Wrap {
private char[] dataArray;
public Wrap() {
dataArray = new char[10];
// 初期化
}
public CharBuffer getBufferCopy() {
return CharBuffer.wrap(dataArray);
}
}
適合コード (asReadOnlyBuffer())
以下の適合コードでは、char 型配列の読取り専用のビューを読取り専用の CharBuffer として返している。標準ライブラリの CharBuffer の実装では、読取り専用 CharBuffer の要素を変更しようとすると java.nio.ReadOnlyBufferException 例外がスローされることが保証されている。
final class Wrap {
private char[] dataArray;
public Wrap() {
dataArray = new char[10];
// 初期化
}
public CharBuffer getBufferCopy() {
return CharBuffer.wrap(dataArray).asReadOnlyBuffer();
}
}
適合コード (コピー)
以下の適合コードでは、新規に割り当てた CharBuffer に char 型配列の内容を明示的にコピーしてから、CharBuffer を返している。悪意ある呼出し元は配列のコピーを変更できるが、元の配列を変更することはできない。
final class Wrap {
private char[] dataArray;
public Wrap() {
dataArray = new char[10];
// 初期化
}
public CharBuffer getBufferCopy() {
CharBuffer cb = CharBuffer.allocate(dataArray.length);
cb.put(dataArray);
return cb;
}
}
違反コード (duplicate())
以下の違反コード例では、duplicate() メソッドを呼び出し、CharBuffer のコピーを作成して返している。duplicate() メソッドの使用契約に定められているように、返されるバッファで使われている配列は、元のバッファで使われている配列と同じものである。呼出し元が CharBuffer のコピーで使われている配列要素を変更すると、元のバッファで使われている配列も変更されることになる。
final class Dup {
CharBuffer cb;
public Dup() {
cb = CharBuffer.allocate(10);
// 初期化
}
public CharBuffer getBufferCopy() {
return cb.duplicate();
}
}
適合コード (asReadOnlyBuffer())
以下の適合コードでは、CharBuffer の読取り専用ビューを返している。
final class Dup {
CharBuffer cb;
public Dup() {
cb = CharBuffer.allocate(10);
// 初期化
}
public CharBuffer getBufferCopy() {
return cb.asReadOnlyBuffer();
}
}
リスク評価
信頼できない呼出し元が、wrap() や duplicate() メソッドを使って作成されたバッファにアクセスできると、コピー元のデータを変更されてしまう可能性がある。
|
ルール |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
|---|---|---|---|---|---|
|
FIO05-J |
中 |
高 |
低 |
P18 |
L1 |
自動検出
この脆弱性を適切に自動検出することは不可能である。ヒューリスティックなアプローチが役に立つかもしれない。
参考文献
|
[API 2014] |
|
|
[Hitchens 2002] |
Section 2.3 "Duplicating Buffers" |
翻訳元
これは以下のページを翻訳したものです。
FIO05-J. Do not expose buffers created using the wrap() or duplicate() methods to untrusted code



