メモ:The CERT Oracle Secure Coding Standard for Java

The CERT Oracle Secure Coding Standard for Java - java - CERT Secure Coding Standards
Javaでセキュアなプログラムを書くための基準。とても詳しく書かれている。
 
重大度が大きいものを流し読みしていて気になった部分をメモ。
 
 
SQLインジェクション対策には準備された文を使う
 
文字列比較のときにはUnicode文字を正規化する
 
不要な文字を削除するときは、削除前に検証を行う
XSSを起こすものがないかチェック→アスキー文字以外を削除…という順序だと、"<scrあipt>"という文字列が検証を通ってしまう、という当然なお話。
 
適切にオートボクシングされているかに注意
Set<Short>.remove(short) のようにすると、shortがShortにボクシングされると見せかけてIntegerにボクシングされ、適切に消去ができない。
 
不正なサブクラスは叩き潰す
イミュータブルであることが期待されるクラスorメソッドを継承orオーバーライドして可変にすると、いろいろ悪いことができたり。
不変でないクラスはサニタイズするしかないか。
 
不変を期待するためには防御的コピーせよ
 
重要なクラスはclone()でコピーされてはいけない
clone()を持っていないクラスでも継承されてコピーできてしまうので、clone()をfinalにする。
 
コンストラクタで例外を投げるのは注意して行う
コンストラクタで例外が発生すると、そのオブジェクトは部分的に初期化された状態で生成される。
このオブジェクトはどこからも参照されていないのですぐガベージコレクトされるが、そのオブジェクトのクラスを継承してファイナライザーをオーバーライドするとそのオブジェクトを捕捉することができる。そうなると困る。
 
clone()内でオーバーライドできるメソッドを呼ばない
 
ぬるぽをキャッチしてはいけない
 
多スレッドで共有される値は可視性(値がスレッド間で整合性を保つこと)を保証する
 
多スレッドで共有される値を読んで書くなら可視性だけでなく原子性も保証する
 
排他制御に使うオブジェクトはちゃんとnewで初期化する
intのボクシングの実態はInteger.valueOf()で、これはキャッシュを使いまわすので駄目。
 
static領域を排他するなら排他用オブジェクトもstaticに
 
部分的に初期化されたオブジェクトを見せない
例えば'SomeObj obj = new Someobj();'というコードがあったとき、SomeObjクラスのコンストラクタが実行される前に変数objへの変数割り当てが起こることがある。
このとき複数スレッドが存在するとobjの過度状態を見ることができ、バグのもととなる。

配列のラッパーとしてのBufferで使用する配列は外部に渡さない
Buffer.wrap()とBuffer.put()は全然違うよ。
 
シリアライズメソッドを可視(非private)にしてはならない
readResolve()とwriteReplace()はprotectedなメンバーメソッドに。
 
staticでない内部クラスをシリアライズ可能にしてはならない
staticな内部クラスはシリアライズしてもいいよ。
 
汚染された変数を権限付きで実行してはならない
 
アクセス可視領域を広げてしまうリフレクションを使ってはいけない
publicメソッドで不用意にリフレクションを使うと、privateメンバーにアクセスできてしまう。
Field.setAccessible(true) は基本的にセキュリティマネージャーがはじいてくれるので、そこまで怖くはないはず。
 
決定的な乱数は使ってはいけない
 
パスワードなどを直書きしてはいけない
 
 
重要そうだけどよく意味が分からなかったもの:
SEC2~7