本日、Java読書会BOF主催の「セキュア・バイ・デザイン」を読む会(第3回)を開催しました。
本日は、第4章安全性を確立する実装テクニックの4.1不変性(immutability)から読み始めました。
読書メモ
クラスが可変となる設計をすると、排他制御が必要で完全性(integrity)が損なわれるので、不変な設計をしましょう
- 不変性の実装は、JDK 17以降は record が使えるのでは?
契約による設計で、速やかな失敗を
受け取った不正なデータをそのままログに出さない
- なぜ? 9章によると、ログを読み込む別システム(ログ管理システム)が不正データを含むログを読み込みXSSになると
- 開発観点ではログに不正データがないと問題切り分けが困難になるが安全性の観点が優先されるべき(この本の趣旨)
妥当性の確認リスト
- オリジン(発生源)の確認
- データ・サイズの確認
- 字句的内容(lexical content)の確認
- 構文(syntax)の確認
- データに対する意味(semantics)の確認
データサイズの確認は、10億桁の文字列を受け取って次の確認(正規表現エンジン等)に読み込ませるといったことを防ぐ意味がある
データに対する意味の確認は、この本ではドメイン・モデルで行うのが適していると著者は言っている
ドメイン・プリミティブはドメイン駆動設計で紹介された値オブジェクトをセキュリティを意識しながら改良したもので、セキュリティ問題の可能性をコードから取り除く
メールアドレスの大文字・小文字で盛り上がる(書籍から脱線)
今日は、脱線した議論が多く、盛り上がりましたが読み進んだページ数は平均を下回っていました。
ドメイン・プリミティブの実装をrecordで再実装してみる
この本は、原書が2021年に出版されていますが、Javaのコード例はJava SE 8の範囲で書かれています。 Javaでは、Java SE 17においてrecordが正式導入されたので、値オブジェクトの実装が少ない記述量で実装できるようになっています。そこで、書籍のドメイン・プリミティブの例をrecordで再実装してみます。
Quantityクラスの例(リスト5.1よりコード抜粋、コメントは私が補足)
public final class Quantity { private final int value; public Quantity(final int value) { inclusiveBetween(1, 200, value); // commons.lang の Validateクラスのstaticメソッドで範囲チェック this.value = value; } public int value() { return value; } pubilc Quantity add(final Quantity addend) { notNull(addend); // commons.lang の Validateクラスのstaticメソッドでnullチェック return new Quantity(value + addend.value); } // ...略(equalsメソッド、hashCodeメソッド、toStringメソッドが略されていると思われる) }
hashcodeやequalsメソッドは「...略」のところに現れるものと想定しておきます。 このクラスをrecord型で記述すると
public record Quantity(int value) { public Quantity { inclusiveBetween(1, 200, value) } public Quantity add(final Quantity addend) { notNull(addend); return new Quantity(value + addend.value); } }
とシンプルに記述でき、フィールドの定義、コンストラクタの定義のうちフィールドへの代入、フィールドのgetterメソッド、equalsメソッド、hashCodeメソッド、toStringメソッドが自動で定義されます。
JDK 19リリースがもうすぐ
読書会開催時の雑談で、もうすぐ JDK 19 がリリースされると話題に上がりました。 JDK 19はどんな機能が入るのだろう?ということでリリースノートを見ると次のような機能が入ります。
JEPでは
- Virtual Threads (preview)
- Vector API (4回目のIncubator)
- Record Patterns (preview)
- Pattern Matching for switch (3回目のpreview)
- Foreign Function & Memory API (preview)
- Structured Concurrency (Incubator)
- Linux/RISC-V Port
JEP以外の更新では(抜粋)
- System.outとSystem.err用のプロパティ stdout.encoding、stderr.encoding
- Unicode 14.0
- 追加のDate-Time Formats。DateTimeFormatter.ofLocalizedPattern("yMMM")などが記述可能