「DDDなんもわからん」な私がセキュア・バイ・デザインを読んでみた
この記事は iCARE Dev アドベントカレンダーの 21 日目の記事です。
こんにちは!iCARE でサーバーサイドエンジニアをしている越川と申します。油断していたらいつの間にか担当日になってしまい、慌てて書きました。
今回は 2021 年に読んだ本の中で個人的に一番面白かった「セキュア・バイ・デザイン 安全なソフトウェア設計」の面白かった章の感想をつらつらと書きたいと思っています。
ちなみに、MANNIG の商品紹介ページで本文を読むことができます。(英語ですが)
なお、本書は DDD(Domain Driven Development)の解説にかなりのページを割いているのですが、本記事内では DDD について深く書くことはせず(というか書けるほど知見もない)
DDD をあまり知らない層でも読めるように書きたいと思います。
第 1 章 なぜ、設計がセキュリティにおいて重要なのか?
本書では、セキュリティを実装すべき機能(feature)として見るのではなく、対応しなければならない心配事(concern)として見るようにする。と述べられています。
例えば、自宅に泥棒の侵入を防ぐためにピッキングしにくい鍵をつけることがあると思いますが、ポストの中に鍵を保管する運用になっていたり、
玄関の鍵は完璧でも窓ガラスがすぐに割れてしまうものだと、完全に侵入を防ぐことはできません。
このように、セキュリティは横断的に見る必要があるのに、機能として見てしまったがために起きた事件が本書で紹介されています。
約 150 年前にスウェーデンの銀行で起きた強盗事件
要約すると、
- 1854 年 3 月 25 日の夜、スウェーデンの Öst-Gotha 銀行で強盗事件が発生
- その銀行の通用口は施錠されていたが、ドアを開けるための鍵は外に吊るされていた
- 金庫室の扉には非常に強力な錠前が付けられていて、ピッキングでその錠前を破ることはほぼ不可能だった
- しかし金庫室の扉に付いている蝶番を壊して金庫室の扉を逆に開ければ、簡単に金庫室に侵入できた
という事件が発生したそうです。「ドアを開けるための鍵は外に吊るされていた」は本当なのか?と疑いたくなりますが、
もしこの銀行の行員の誰かがセキュリティを機能ではなく対応しなければならない心配事として見ていれば防げたのではないか?と本書では述べられています。
これは私の偏見ですが、状況を察するに、「通用口は施錠しているし金庫室の扉には非常に強力な錠前がついているのだからネズミの一匹でも入れないだろう」と高を括って、根拠のない自信を持っていたのでしょう。
。。。よく考えたら自分も開発中に同様のメンタリティになった覚えがありますね。人の事は言えませんでした。
第 2 章『ハムレット』の悲劇
とあるオンライン書店サイトでマイナス値の入力が可能だったため、多大な損失を被ってしまったという事例が紹介されています。
本書内では、なぜそのような事態を招いたのかの原因の一つとして、「浅いモデリング」にあるとの意見を述べています。
浅いモデリング
「浅いモデリング」とは、開発者がうまくモデリングできたと最初に思った時点で、それ以上は深く考えたり考慮したりすることをやめてしまう類の行為を言います。
例えば「本」をモデリングする際に、ISBN コードや価格や冊数を属性として持たせると決めた場合、
本が持つ属性をプリミティブな基本データ型(Integer, String, Float 等)で表現することで終わらせてしまうことが「浅いモデリング」の具体的な事例です。
と偉そうに書いているのですが、私も見に覚えがあったのでここで供養させてください。
身に覚えのある例その 1
以前請求書めいたものを PDF で出力するシステムのモデリングをしているときに、
会社名が変わり得ることを考慮できず、請求当時の会社名が出力できなくなってしまったことがありました。
当時は請求クラスに会社名を持たせることで対応しましたが、実装に入る前に考慮できれば良かったと今なら思います。。。
見に覚えのある例その 2
郵便番号や電話番号の形式を明確に定義せず、ハイフン入りやハイフン抜きのデータが DB に保存されてしまい、
ハイフン入りかハイフン抜きかを考慮した実装をせざるを得ない状況になってしまい、負債にしてしまったことがありました。
事前に、「ハイフンを含むか?」「国際電話まで考慮した桁数にするか?」等の考慮を入れておくべきだったと思います。。。
突然の供養へのお付き合い誠にありがとうございました。
深いモデリング
本文では「浅いモデリング」に対して「深いモデリング」という概念も提唱されています。
「深いモデリング」を行うには、作ろうとしているシステムの概念を「この概念をどのようにコードに落とし込むか?」ではなく「どうすれば理解できるようになるか?」を意識することが重要だと述べられていました。
例えば、「ISBN コードは文字列」だけで終わらすのではなく、
「ISBN コードは最初の 3 桁が 978 もしくは 979 で、次の 1 桁は言語圏を表す数字が入り、次の 3 桁は出版社の記号、次の 5 桁は書名記号、次の 1 桁はチェックデジットで、間をハイフンで繋いだ 13 桁の数字で構成される文字列」
という定義だと分かっていれば、コードで表現するときもバリデーションをかける等を行って、 ISBN コードでない値の混入を防ぐことにつながります。これは巡り巡って、<や>などの文字の混入を防ぎ、結果として脆弱性を防ぐことにも繋がります。
価格も、税抜きなのか税込みなのかでモデリングが変わってくるかと思います。冊数も取り得る値の範囲を決めるべきかと。
このように、「ISBN コードは文字列だ!以上!」で終わらすだけでなく、さらに深く考察して概念を定義することを「暗黙的な表現から明示的な表現への転換」と本書で述べています。
(対象の概念を簡単にモデリングしてドメインエキスパートにヒアリングすることなく、暗黙的な表現のままですぐに実装に入ることはよくやってしまっていたなぁ、、、)
第 11 章 保険料の支払いなしに成立してしまった保険契約
個人的には一番学び(反面教師としての側面で)があった章です。
とある保険会社にて、「支払い」の概念が複数のシステム間で異なった解釈になってしまい、
保険料の支払いなしに成立してしまった保険契約があったという事例が紹介されています。
本文ではそれがなぜ発生したのか?について克明に記されています。
複数サービスへの分割の弊害
最初は保険料の支払い管理と保険証書の郵送のみを管理していたシステムだったんですが、
ビジネスが順調に展開される中でシステムも複雑で巨大なものになり、
2 つのコンテキスト間(経理チームと保険チーム)でチームとシステムを分割することになったそうです。
そこに新たな支払い手段である「銀行振り込み」が登場し、システムの改修を行ったが、その際に銀行振り込みの場合の考慮が足りず、
保険料の支払いの前に保険証書が顧客の手元に届いたという顛末になります。
本書では「なぜ考慮が足りなくなったのか?」「考慮が足りなくなる事態をどうすれば防ぐことができたのか?」についても考察しています。
弊社では今年からチーム制を導入しており、サービス別にシステムを分割しているところまでは行っていないので本事例とは毛色が異なりますが、
チーム間でそれぞれのドメイン知識を完全に持たない状況は避けるべきだなと思いました。
この章は本書の中でも屈指の面白さなので、是非読んでみてください。
まとめ
今回は実際に起きた事例を中心にご紹介しましたが、他の章では DDD についての考察と
DDD とセキュア・バイ・デザインの繋がりやセキュア・バイ・デザインをどうレガシーコードに適用していくか?など、盛り沢山な書籍になっていますので、
セキュアなアプリケーションの作り方に悩んでいる方や DDD をちょっとかじってみたけど実際どう実装すればいいの?といった方にも読んで頂くといいと思います。
株式会社 iCARE ではエンジニア採用を強化しています
各ポジションにて求人をしております。働くひとの健康を世界中に創る事業にご興味のある方は、まずはカジュアル面談からでもお気軽ご連絡ください!
紹介商談も募集しております
弊社、株式会社 iCARE では、企業が従業員の健康管理をする SaaS の商談をしていただける企業さまをご紹介いただける企業さまを募っております。
健康管理にお困りの人事の方のお知り合いがいらっしゃいましたら是非株式会社 iCARE までご連絡くださいませ!